1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985-1986, 1993-1995, 1997-2011
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
24 #include "intervals.h"
26 #include "character.h"
28 #include "blockinput.h"
29 #include "region-cache.h"
35 static void insert_from_string_1 (Lisp_Object string
,
36 EMACS_INT pos
, EMACS_INT pos_byte
,
37 EMACS_INT nchars
, EMACS_INT nbytes
,
38 int inherit
, int before_markers
);
39 static void insert_from_buffer_1 (struct buffer
*buf
,
40 EMACS_INT from
, EMACS_INT nchars
,
42 static void gap_left (EMACS_INT charpos
, EMACS_INT bytepos
, int newgap
);
43 static void gap_right (EMACS_INT charpos
, EMACS_INT bytepos
);
44 static void adjust_markers_gap_motion (EMACS_INT from
, EMACS_INT to
,
46 static void adjust_markers_for_insert (EMACS_INT from
, EMACS_INT from_byte
,
47 EMACS_INT to
, EMACS_INT to_byte
,
49 static void adjust_markers_for_replace (EMACS_INT
, EMACS_INT
, EMACS_INT
,
50 EMACS_INT
, EMACS_INT
, EMACS_INT
);
51 static void adjust_point (EMACS_INT nchars
, EMACS_INT nbytes
);
53 Lisp_Object
Fcombine_after_change_execute (void);
55 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
56 describing changes which happened while combine_after_change_calls
57 was nonzero. We use this to decide how to call them
58 once the deferral ends.
61 BEG-UNCHANGED is the number of chars before the changed range.
62 END-UNCHANGED is the number of chars after the changed range,
63 and CHANGE-AMOUNT is the number of characters inserted by the change
64 (negative for a deletion). */
65 Lisp_Object combine_after_change_list
;
67 /* Buffer which combine_after_change_list is about. */
68 Lisp_Object combine_after_change_buffer
;
70 Lisp_Object Qinhibit_modification_hooks
;
72 #define CHECK_MARKERS() \
73 if (check_markers_debug_flag) \
80 register struct Lisp_Marker
*tail
;
81 int multibyte
= ! NILP (BVAR (current_buffer
, enable_multibyte_characters
));
83 for (tail
= BUF_MARKERS (current_buffer
); tail
; tail
= tail
->next
)
85 if (tail
->buffer
->text
!= current_buffer
->text
)
87 if (tail
->charpos
> Z
)
89 if (tail
->bytepos
> Z_BYTE
)
91 if (multibyte
&& ! CHAR_HEAD_P (FETCH_BYTE (tail
->bytepos
)))
96 /* Move gap to position CHARPOS.
97 Note that this can quit! */
100 move_gap (EMACS_INT charpos
)
102 move_gap_both (charpos
, charpos_to_bytepos (charpos
));
105 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
106 Note that this can quit! */
109 move_gap_both (EMACS_INT charpos
, EMACS_INT bytepos
)
111 if (bytepos
< GPT_BYTE
)
112 gap_left (charpos
, bytepos
, 0);
113 else if (bytepos
> GPT_BYTE
)
114 gap_right (charpos
, bytepos
);
117 /* Move the gap to a position less than the current GPT.
118 BYTEPOS describes the new position as a byte position,
119 and CHARPOS is the corresponding char position.
120 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
123 gap_left (EMACS_INT charpos
, EMACS_INT bytepos
, int newgap
)
125 register unsigned char *to
, *from
;
126 register EMACS_INT i
;
130 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
137 /* Now copy the characters. To move the gap down,
138 copy characters up. */
142 /* I gets number of characters left to copy. */
143 i
= new_s1
- bytepos
;
146 /* If a quit is requested, stop copying now.
147 Change BYTEPOS to be where we have actually moved the gap to. */
151 charpos
= BYTE_TO_CHAR (bytepos
);
154 /* Move at most 32000 chars before checking again for a quit. */
159 memmove (to
, from
, i
);
162 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
163 BYTEPOS is where the loop above stopped, which may be what was specified
164 or may be where a quit was detected. */
165 adjust_markers_gap_motion (bytepos
, GPT_BYTE
, GAP_SIZE
);
168 if (bytepos
< charpos
)
170 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
174 /* Move the gap to a position greater than the current GPT.
175 BYTEPOS describes the new position as a byte position,
176 and CHARPOS is the corresponding char position. */
179 gap_right (EMACS_INT charpos
, EMACS_INT bytepos
)
181 register unsigned char *to
, *from
;
182 register EMACS_INT i
;
185 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
192 /* Now copy the characters. To move the gap up,
193 copy characters down. */
197 /* I gets number of characters left to copy. */
198 i
= bytepos
- new_s1
;
201 /* If a quit is requested, stop copying now.
202 Change BYTEPOS to be where we have actually moved the gap to. */
206 charpos
= BYTE_TO_CHAR (bytepos
);
209 /* Move at most 32000 chars before checking again for a quit. */
213 memmove (to
, from
, i
);
217 adjust_markers_gap_motion (GPT_BYTE
+ GAP_SIZE
, bytepos
+ GAP_SIZE
,
221 if (bytepos
< charpos
)
223 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
227 /* Add AMOUNT to the byte position of every marker in the current buffer
228 whose current byte position is between FROM (exclusive) and TO (inclusive).
230 Also, any markers past the outside of that interval, in the direction
231 of adjustment, are first moved back to the near end of the interval
232 and then adjusted by AMOUNT.
234 When the latter adjustment is done, if AMOUNT is negative,
235 we record the adjustment for undo. (This case happens only for
238 The markers' character positions are not altered,
239 because gap motion does not affect character positions. */
241 int adjust_markers_test
;
244 adjust_markers_gap_motion (EMACS_INT from
, EMACS_INT to
, EMACS_INT amount
)
246 /* Now that a marker has a bytepos, not counting the gap,
247 nothing needs to be done here. */
250 register struct Lisp_Marker
*m
;
251 register EMACS_INT mpos
;
253 marker
= BUF_MARKERS (current_buffer
);
255 while (!NILP (marker
))
257 m
= XMARKER (marker
);
261 if (mpos
> to
&& mpos
< to
+ amount
)
263 if (adjust_markers_test
)
270 /* Here's the case where a marker is inside text being deleted.
271 AMOUNT can be negative for gap motion, too,
272 but then this range contains no markers. */
273 if (mpos
> from
+ amount
&& mpos
<= from
)
275 if (adjust_markers_test
)
277 mpos
= from
+ amount
;
280 if (mpos
> from
&& mpos
<= to
)
288 /* Adjust all markers for a deletion
289 whose range in bytes is FROM_BYTE to TO_BYTE.
290 The range in charpos is FROM to TO.
292 This function assumes that the gap is adjacent to
293 or inside of the range being deleted. */
296 adjust_markers_for_delete (EMACS_INT from
, EMACS_INT from_byte
,
297 EMACS_INT to
, EMACS_INT to_byte
)
300 register struct Lisp_Marker
*m
;
301 register EMACS_INT charpos
;
303 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
305 charpos
= m
->charpos
;
310 /* If the marker is after the deletion,
311 relocate by number of chars / bytes deleted. */
314 m
->charpos
-= to
- from
;
315 m
->bytepos
-= to_byte
- from_byte
;
317 /* Here's the case where a marker is inside text being deleted. */
318 else if (charpos
> from
)
320 if (! m
->insertion_type
)
321 { /* Normal markers will end up at the beginning of the
322 re-inserted text after undoing a deletion, and must be
323 adjusted to move them to the correct place. */
324 XSETMISC (marker
, m
);
325 record_marker_adjustment (marker
, from
- charpos
);
327 else if (charpos
< to
)
328 { /* Before-insertion markers will automatically move forward
329 upon re-inserting the deleted text, so we have to arrange
330 for them to move backward to the correct position. */
331 XSETMISC (marker
, m
);
332 record_marker_adjustment (marker
, to
- charpos
);
335 m
->bytepos
= from_byte
;
337 /* Here's the case where a before-insertion marker is immediately
338 before the deleted region. */
339 else if (charpos
== from
&& m
->insertion_type
)
341 /* Undoing the change uses normal insertion, which will
342 incorrectly make MARKER move forward, so we arrange for it
343 to then move backward to the correct place at the beginning
344 of the deleted region. */
345 XSETMISC (marker
, m
);
346 record_marker_adjustment (marker
, to
- from
);
352 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
353 to TO / TO_BYTE. We have to relocate the charpos of every marker
354 that points after the insertion (but not their bytepos).
356 When a marker points at the insertion point,
357 we advance it if either its insertion-type is t
358 or BEFORE_MARKERS is true. */
361 adjust_markers_for_insert (EMACS_INT from
, EMACS_INT from_byte
,
362 EMACS_INT to
, EMACS_INT to_byte
, int before_markers
)
364 struct Lisp_Marker
*m
;
366 EMACS_INT nchars
= to
- from
;
367 EMACS_INT nbytes
= to_byte
- from_byte
;
369 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
371 eassert (m
->bytepos
>= m
->charpos
372 && m
->bytepos
- m
->charpos
<= Z_BYTE
- Z
);
374 if (m
->bytepos
== from_byte
)
376 if (m
->insertion_type
|| before_markers
)
378 m
->bytepos
= to_byte
;
380 if (m
->insertion_type
)
384 else if (m
->bytepos
> from_byte
)
386 m
->bytepos
+= nbytes
;
387 m
->charpos
+= nchars
;
391 /* Adjusting only markers whose insertion-type is t may result in
392 - disordered start and end in overlays, and
393 - disordered overlays in the slot `overlays_before' of current_buffer. */
396 fix_start_end_in_overlays(from
, to
);
397 fix_overlays_before (current_buffer
, from
, to
);
401 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
403 This is used only when the value of point changes due to an insert
404 or delete; it does not represent a conceptual change in point as a
405 marker. In particular, point is not crossing any interval
406 boundaries, so there's no need to use the usual SET_PT macro. In
407 fact it would be incorrect to do so, because either the old or the
408 new value of point is out of sync with the current set of
412 adjust_point (EMACS_INT nchars
, EMACS_INT nbytes
)
414 BUF_PT (current_buffer
) += nchars
;
415 BUF_PT_BYTE (current_buffer
) += nbytes
;
417 /* In a single-byte buffer, the two positions must be equal. */
418 eassert (PT_BYTE
>= PT
&& PT_BYTE
- PT
<= ZV_BYTE
- ZV
);
421 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
422 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
423 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
427 adjust_markers_for_replace (EMACS_INT from
, EMACS_INT from_byte
,
428 EMACS_INT old_chars
, EMACS_INT old_bytes
,
429 EMACS_INT new_chars
, EMACS_INT new_bytes
)
431 register struct Lisp_Marker
*m
;
432 EMACS_INT prev_to_byte
= from_byte
+ old_bytes
;
433 EMACS_INT diff_chars
= new_chars
- old_chars
;
434 EMACS_INT diff_bytes
= new_bytes
- old_bytes
;
436 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
438 if (m
->bytepos
>= prev_to_byte
)
440 m
->charpos
+= diff_chars
;
441 m
->bytepos
+= diff_bytes
;
443 else if (m
->bytepos
> from_byte
)
446 m
->bytepos
= from_byte
;
454 /* Make the gap NBYTES_ADDED bytes longer. */
457 make_gap_larger (EMACS_INT nbytes_added
)
460 EMACS_INT real_gap_loc
;
461 EMACS_INT real_gap_loc_byte
;
462 EMACS_INT old_gap_size
;
464 /* If we have to get more space, get enough to last a while. */
465 nbytes_added
+= 2000;
467 { EMACS_INT total_size
= Z_BYTE
- BEG_BYTE
+ GAP_SIZE
+ nbytes_added
;
469 /* Don't allow a buffer size that won't fit in a Lisp integer. */
470 || total_size
!= XINT (make_number (total_size
))
471 /* Don't allow a buffer size that won't fit in an int
472 even if it will fit in a Lisp integer.
473 That won't work because so many places still use `int'. */
474 || total_size
!= (EMACS_INT
) (int) total_size
)
475 error ("Buffer exceeds maximum size");
478 enlarge_buffer_text (current_buffer
, nbytes_added
);
480 /* Prevent quitting in move_gap. */
485 real_gap_loc_byte
= GPT_BYTE
;
486 old_gap_size
= GAP_SIZE
;
488 /* Call the newly allocated space a gap at the end of the whole space. */
490 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
491 GAP_SIZE
= nbytes_added
;
493 /* Move the new gap down to be consecutive with the end of the old one.
494 This adjusts the markers properly too. */
495 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
497 /* Now combine the two into one large gap. */
498 GAP_SIZE
+= old_gap_size
;
500 GPT_BYTE
= real_gap_loc_byte
;
509 /* Make the gap NBYTES_REMOVED bytes shorter. */
512 make_gap_smaller (EMACS_INT nbytes_removed
)
515 EMACS_INT real_gap_loc
;
516 EMACS_INT real_gap_loc_byte
;
518 EMACS_INT real_Z_byte
;
519 EMACS_INT real_beg_unchanged
;
520 EMACS_INT new_gap_size
;
522 /* Make sure the gap is at least 20 bytes. */
523 if (GAP_SIZE
- nbytes_removed
< 20)
524 nbytes_removed
= GAP_SIZE
- 20;
526 /* Prevent quitting in move_gap. */
531 real_gap_loc_byte
= GPT_BYTE
;
532 new_gap_size
= GAP_SIZE
- nbytes_removed
;
534 real_Z_byte
= Z_BYTE
;
535 real_beg_unchanged
= BEG_UNCHANGED
;
537 /* Pretend that the last unwanted part of the gap is the entire gap,
538 and that the first desired part of the gap is part of the buffer
540 memset (GPT_ADDR
, 0, new_gap_size
);
542 GPT_BYTE
+= new_gap_size
;
544 Z_BYTE
+= new_gap_size
;
545 GAP_SIZE
= nbytes_removed
;
547 /* Move the unwanted pretend gap to the end of the buffer. This
548 adjusts the markers properly too. */
549 gap_right (Z
, Z_BYTE
);
551 enlarge_buffer_text (current_buffer
, -nbytes_removed
);
553 /* Now restore the desired gap. */
554 GAP_SIZE
= new_gap_size
;
556 GPT_BYTE
= real_gap_loc_byte
;
558 Z_BYTE
= real_Z_byte
;
559 BEG_UNCHANGED
= real_beg_unchanged
;
568 make_gap (EMACS_INT nbytes_added
)
570 if (nbytes_added
>= 0)
571 make_gap_larger (nbytes_added
);
572 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
574 make_gap_smaller (-nbytes_added
);
578 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
579 FROM_MULTIBYTE says whether the incoming text is multibyte.
580 TO_MULTIBYTE says whether to store the text as multibyte.
581 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
583 Return the number of bytes stored at TO_ADDR. */
586 copy_text (const unsigned char *from_addr
, unsigned char *to_addr
,
587 EMACS_INT nbytes
, int from_multibyte
, int to_multibyte
)
589 if (from_multibyte
== to_multibyte
)
591 memcpy (to_addr
, from_addr
, nbytes
);
594 else if (from_multibyte
)
596 EMACS_INT nchars
= 0;
597 EMACS_INT bytes_left
= nbytes
;
598 Lisp_Object tbl
= Qnil
;
600 while (bytes_left
> 0)
603 c
= STRING_CHAR_AND_LENGTH (from_addr
, thislen
);
604 if (! ASCII_CHAR_P (c
))
607 from_addr
+= thislen
;
608 bytes_left
-= thislen
;
615 unsigned char *initial_to_addr
= to_addr
;
617 /* Convert single-byte to multibyte. */
620 int c
= *from_addr
++;
622 if (!ASCII_CHAR_P (c
))
624 c
= BYTE8_TO_CHAR (c
);
625 to_addr
+= CHAR_STRING (c
, to_addr
);
629 /* Special case for speed. */
630 *to_addr
++ = c
, nbytes
--;
632 return to_addr
- initial_to_addr
;
636 /* Return the number of bytes it would take
637 to convert some single-byte text to multibyte.
638 The single-byte text consists of NBYTES bytes at PTR. */
641 count_size_as_multibyte (const unsigned char *ptr
, EMACS_INT nbytes
)
644 EMACS_INT outgoing_nbytes
= 0;
646 for (i
= 0; i
< nbytes
; i
++)
648 unsigned int c
= *ptr
++;
650 if (ASCII_CHAR_P (c
))
654 c
= BYTE8_TO_CHAR (c
);
655 outgoing_nbytes
+= CHAR_BYTES (c
);
659 return outgoing_nbytes
;
662 /* Insert a string of specified length before point.
663 This function judges multibyteness based on
664 enable_multibyte_characters in the current buffer;
665 it never converts between single-byte and multibyte.
667 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
668 prepare_to_modify_buffer could relocate the text. */
671 insert (const char *string
, EMACS_INT nbytes
)
675 EMACS_INT len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
676 insert_1_both (string
, len
, nbytes
, 0, 1, 0);
678 signal_after_change (opoint
, 0, len
);
679 update_compositions (opoint
, PT
, CHECK_BORDER
);
683 /* Likewise, but inherit text properties from neighboring characters. */
686 insert_and_inherit (const char *string
, EMACS_INT nbytes
)
690 EMACS_INT len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
691 insert_1_both (string
, len
, nbytes
, 1, 1, 0);
693 signal_after_change (opoint
, 0, len
);
694 update_compositions (opoint
, PT
, CHECK_BORDER
);
698 /* Insert the character C before point. Do not inherit text properties. */
703 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
706 if (! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
707 len
= CHAR_STRING (c
, str
);
714 insert ((char *) str
, len
);
717 /* Insert the null-terminated string S before point. */
720 insert_string (const char *s
)
722 insert (s
, strlen (s
));
725 /* Like `insert' except that all markers pointing at the place where
726 the insertion happens are adjusted to point after it.
727 Don't use this function to insert part of a Lisp string,
728 since gc could happen and relocate it. */
731 insert_before_markers (const char *string
, EMACS_INT nbytes
)
735 EMACS_INT len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
736 insert_1_both (string
, len
, nbytes
, 0, 1, 1);
738 signal_after_change (opoint
, 0, len
);
739 update_compositions (opoint
, PT
, CHECK_BORDER
);
743 /* Likewise, but inherit text properties from neighboring characters. */
746 insert_before_markers_and_inherit (const char *string
,
751 EMACS_INT len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
752 insert_1_both (string
, len
, nbytes
, 1, 1, 1);
754 signal_after_change (opoint
, 0, len
);
755 update_compositions (opoint
, PT
, CHECK_BORDER
);
759 /* Subroutine used by the insert functions above. */
762 insert_1 (const char *string
, EMACS_INT nbytes
,
763 int inherit
, int prepare
, int before_markers
)
765 insert_1_both (string
, chars_in_text ((unsigned char *) string
, nbytes
),
766 nbytes
, inherit
, prepare
, before_markers
);
770 #ifdef BYTE_COMBINING_DEBUG
772 /* See if the bytes before POS/POS_BYTE combine with bytes
773 at the start of STRING to form a single character.
774 If so, return the number of bytes at the start of STRING
775 which combine in this way. Otherwise, return 0. */
778 count_combining_before (const unsigned char *string
, EMACS_INT length
,
779 EMACS_INT pos
, EMACS_INT pos_byte
)
781 int len
, combining_bytes
;
782 const unsigned char *p
;
784 if (NILP (current_buffer
->enable_multibyte_characters
))
787 /* At first, we can exclude the following cases:
788 (1) STRING[0] can't be a following byte of multibyte sequence.
789 (2) POS is the start of the current buffer.
790 (3) A character before POS is not a multibyte character. */
791 if (length
== 0 || CHAR_HEAD_P (*string
)) /* case (1) */
793 if (pos_byte
== BEG_BYTE
) /* case (2) */
796 p
= BYTE_POS_ADDR (pos_byte
- 1);
797 while (! CHAR_HEAD_P (*p
)) p
--, len
++;
798 if (! LEADING_CODE_P (*p
)) /* case (3) */
801 combining_bytes
= BYTES_BY_CHAR_HEAD (*p
) - len
;
802 if (combining_bytes
<= 0)
803 /* The character preceding POS is, complete and no room for
804 combining bytes (combining_bytes == 0), or an independent 8-bit
805 character (combining_bytes < 0). */
808 /* We have a combination situation. Count the bytes at STRING that
811 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
814 return (combining_bytes
< p
- string
? combining_bytes
: p
- string
);
817 /* See if the bytes after POS/POS_BYTE combine with bytes
818 at the end of STRING to form a single character.
819 If so, return the number of bytes after POS/POS_BYTE
820 which combine in this way. Otherwise, return 0. */
823 count_combining_after (const unsigned char *string
,
824 EMACS_INT length
, EMACS_INT pos
, EMACS_INT pos_byte
)
826 EMACS_INT opos_byte
= pos_byte
;
831 if (NILP (current_buffer
->enable_multibyte_characters
))
834 /* At first, we can exclude the following cases:
835 (1) The last byte of STRING is an ASCII.
836 (2) POS is the last of the current buffer.
837 (3) A character at POS can't be a following byte of multibyte
839 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1])) /* case (1) */
841 if (pos_byte
== Z_BYTE
) /* case (2) */
843 bufp
= BYTE_POS_ADDR (pos_byte
);
844 if (CHAR_HEAD_P (*bufp
)) /* case (3) */
848 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
854 /* All characters in STRING are not character head. We must
855 check also preceding bytes at POS. We are sure that the gap
857 unsigned char *p
= BEG_ADDR
;
859 while (i
>= 0 && ! CHAR_HEAD_P (p
[i
]))
861 if (i
< 0 || !LEADING_CODE_P (p
[i
]))
864 bytes
= BYTES_BY_CHAR_HEAD (p
[i
]);
865 return (bytes
<= pos_byte
- 1 - i
+ length
867 : bytes
- (pos_byte
- 1 - i
+ length
));
869 if (!LEADING_CODE_P (string
[i
]))
872 bytes
= BYTES_BY_CHAR_HEAD (string
[i
]) - (length
- i
);
874 while (!CHAR_HEAD_P (*bufp
)) bufp
++, pos_byte
++;
876 return (bytes
<= pos_byte
- opos_byte
? bytes
: pos_byte
- opos_byte
);
882 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
883 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
884 are the same as in insert_1. */
887 insert_1_both (const char *string
,
888 EMACS_INT nchars
, EMACS_INT nbytes
,
889 int inherit
, int prepare
, int before_markers
)
894 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
898 /* Do this before moving and increasing the gap,
899 because the before-change hooks might move the gap
900 or make it smaller. */
901 prepare_to_modify_buffer (PT
, PT
, NULL
);
904 move_gap_both (PT
, PT_BYTE
);
905 if (GAP_SIZE
< nbytes
)
906 make_gap (nbytes
- GAP_SIZE
);
908 #ifdef BYTE_COMBINING_DEBUG
909 if (count_combining_before (string
, nbytes
, PT
, PT_BYTE
)
910 || count_combining_after (string
, nbytes
, PT
, PT_BYTE
))
914 /* Record deletion of the surrounding text that combines with
915 the insertion. This, together with recording the insertion,
916 will add up to the right stuff in the undo list. */
917 record_insert (PT
, nchars
);
919 CHARS_MODIFF
= MODIFF
;
921 memcpy (GPT_ADDR
, string
, nbytes
);
930 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
935 /* The insert may have been in the unchanged region, so check again. */
936 if (Z
- GPT
< END_UNCHANGED
)
937 END_UNCHANGED
= Z
- GPT
;
939 adjust_overlays_for_insert (PT
, nchars
);
940 adjust_markers_for_insert (PT
, PT_BYTE
,
941 PT
+ nchars
, PT_BYTE
+ nbytes
,
944 if (BUF_INTERVALS (current_buffer
) != 0)
945 offset_intervals (current_buffer
, PT
, nchars
);
947 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
948 set_text_properties (make_number (PT
), make_number (PT
+ nchars
),
951 adjust_point (nchars
, nbytes
);
956 /* Insert the part of the text of STRING, a Lisp object assumed to be
957 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
958 starting at position POS / POS_BYTE. If the text of STRING has properties,
959 copy them into the buffer.
961 It does not work to use `insert' for this, because a GC could happen
962 before we copy the stuff into the buffer, and relocate the string
963 without insert noticing. */
966 insert_from_string (Lisp_Object string
, EMACS_INT pos
, EMACS_INT pos_byte
,
967 EMACS_INT length
, EMACS_INT length_byte
, int inherit
)
969 EMACS_INT opoint
= PT
;
971 if (SCHARS (string
) == 0)
974 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
976 signal_after_change (opoint
, 0, PT
- opoint
);
977 update_compositions (opoint
, PT
, CHECK_BORDER
);
980 /* Like `insert_from_string' except that all markers pointing
981 at the place where the insertion happens are adjusted to point after it. */
984 insert_from_string_before_markers (Lisp_Object string
,
985 EMACS_INT pos
, EMACS_INT pos_byte
,
986 EMACS_INT length
, EMACS_INT length_byte
,
989 EMACS_INT opoint
= PT
;
991 if (SCHARS (string
) == 0)
994 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
996 signal_after_change (opoint
, 0, PT
- opoint
);
997 update_compositions (opoint
, PT
, CHECK_BORDER
);
1000 /* Subroutine of the insertion functions above. */
1003 insert_from_string_1 (Lisp_Object string
, EMACS_INT pos
, EMACS_INT pos_byte
,
1004 EMACS_INT nchars
, EMACS_INT nbytes
,
1005 int inherit
, int before_markers
)
1007 struct gcpro gcpro1
;
1008 EMACS_INT outgoing_nbytes
= nbytes
;
1011 /* Make OUTGOING_NBYTES describe the text
1012 as it will be inserted in this buffer. */
1014 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1015 outgoing_nbytes
= nchars
;
1016 else if (! STRING_MULTIBYTE (string
))
1018 = count_size_as_multibyte (SDATA (string
) + pos_byte
,
1022 /* Do this before moving and increasing the gap,
1023 because the before-change hooks might move the gap
1024 or make it smaller. */
1025 prepare_to_modify_buffer (PT
, PT
, NULL
);
1028 move_gap_both (PT
, PT_BYTE
);
1029 if (GAP_SIZE
< outgoing_nbytes
)
1030 make_gap (outgoing_nbytes
- GAP_SIZE
);
1033 /* Copy the string text into the buffer, perhaps converting
1034 between single-byte and multibyte. */
1035 copy_text (SDATA (string
) + pos_byte
, GPT_ADDR
, nbytes
,
1036 STRING_MULTIBYTE (string
),
1037 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1039 #ifdef BYTE_COMBINING_DEBUG
1040 /* We have copied text into the gap, but we have not altered
1041 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1042 to these functions and get the same results as we would
1043 have got earlier on. Meanwhile, PT_ADDR does point to
1044 the text that has been stored by copy_text. */
1045 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1046 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1050 record_insert (PT
, nchars
);
1052 CHARS_MODIFF
= MODIFF
;
1054 GAP_SIZE
-= outgoing_nbytes
;
1058 GPT_BYTE
+= outgoing_nbytes
;
1059 ZV_BYTE
+= outgoing_nbytes
;
1060 Z_BYTE
+= outgoing_nbytes
;
1061 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1066 /* The insert may have been in the unchanged region, so check again. */
1067 if (Z
- GPT
< END_UNCHANGED
)
1068 END_UNCHANGED
= Z
- GPT
;
1070 adjust_overlays_for_insert (PT
, nchars
);
1071 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1072 PT_BYTE
+ outgoing_nbytes
,
1075 offset_intervals (current_buffer
, PT
, nchars
);
1077 intervals
= STRING_INTERVALS (string
);
1078 /* Get the intervals for the part of the string we are inserting. */
1079 if (nbytes
< SBYTES (string
))
1080 intervals
= copy_intervals (intervals
, pos
, nchars
);
1082 /* Insert those intervals. */
1083 graft_intervals_into_buffer (intervals
, PT
, nchars
,
1084 current_buffer
, inherit
);
1086 adjust_point (nchars
, outgoing_nbytes
);
1091 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1092 starting at GPT_ADDR. */
1095 insert_from_gap (EMACS_INT nchars
, EMACS_INT nbytes
)
1097 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1100 record_insert (GPT
, nchars
);
1110 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1115 adjust_overlays_for_insert (GPT
- nchars
, nchars
);
1116 adjust_markers_for_insert (GPT
- nchars
, GPT_BYTE
- nbytes
,
1119 if (BUF_INTERVALS (current_buffer
) != 0)
1121 offset_intervals (current_buffer
, GPT
- nchars
, nchars
);
1122 graft_intervals_into_buffer (NULL_INTERVAL
, GPT
- nchars
, nchars
,
1126 if (GPT
- nchars
< PT
)
1127 adjust_point (nchars
, nbytes
);
1132 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1133 current buffer. If the text in BUF has properties, they are absorbed
1134 into the current buffer.
1136 It does not work to use `insert' for this, because a malloc could happen
1137 and relocate BUF's text before the copy happens. */
1140 insert_from_buffer (struct buffer
*buf
,
1141 EMACS_INT charpos
, EMACS_INT nchars
, int inherit
)
1143 EMACS_INT opoint
= PT
;
1145 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1146 signal_after_change (opoint
, 0, PT
- opoint
);
1147 update_compositions (opoint
, PT
, CHECK_BORDER
);
1151 insert_from_buffer_1 (struct buffer
*buf
,
1152 EMACS_INT from
, EMACS_INT nchars
, int inherit
)
1154 register Lisp_Object temp
;
1155 EMACS_INT chunk
, chunk_expanded
;
1156 EMACS_INT from_byte
= buf_charpos_to_bytepos (buf
, from
);
1157 EMACS_INT to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1158 EMACS_INT incoming_nbytes
= to_byte
- from_byte
;
1159 EMACS_INT outgoing_nbytes
= incoming_nbytes
;
1162 /* Make OUTGOING_NBYTES describe the text
1163 as it will be inserted in this buffer. */
1165 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1166 outgoing_nbytes
= nchars
;
1167 else if (NILP (BVAR (buf
, enable_multibyte_characters
)))
1169 EMACS_INT outgoing_before_gap
= 0;
1170 EMACS_INT outgoing_after_gap
= 0;
1172 if (from
< BUF_GPT (buf
))
1174 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1175 if (chunk
> incoming_nbytes
)
1176 chunk
= incoming_nbytes
;
1178 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1184 if (chunk
< incoming_nbytes
)
1186 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
,
1188 incoming_nbytes
- chunk
);
1190 outgoing_nbytes
= outgoing_before_gap
+ outgoing_after_gap
;
1193 /* Make sure point-max won't overflow after this insertion. */
1194 XSETINT (temp
, outgoing_nbytes
+ Z
);
1195 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1196 error ("Maximum buffer size exceeded");
1198 /* Do this before moving and increasing the gap,
1199 because the before-change hooks might move the gap
1200 or make it smaller. */
1201 prepare_to_modify_buffer (PT
, PT
, NULL
);
1204 move_gap_both (PT
, PT_BYTE
);
1205 if (GAP_SIZE
< outgoing_nbytes
)
1206 make_gap (outgoing_nbytes
- GAP_SIZE
);
1208 if (from
< BUF_GPT (buf
))
1210 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1211 if (chunk
> incoming_nbytes
)
1212 chunk
= incoming_nbytes
;
1213 /* Record number of output bytes, so we know where
1214 to put the output from the second copy_text. */
1216 = copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1218 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1219 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1222 chunk_expanded
= chunk
= 0;
1224 if (chunk
< incoming_nbytes
)
1225 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1226 GPT_ADDR
+ chunk_expanded
, incoming_nbytes
- chunk
,
1227 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1228 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1230 #ifdef BYTE_COMBINING_DEBUG
1231 /* We have copied text into the gap, but we have not altered
1232 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1233 to these functions and get the same results as we would
1234 have got earlier on. Meanwhile, GPT_ADDR does point to
1235 the text that has been stored by copy_text. */
1236 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1237 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1241 record_insert (PT
, nchars
);
1243 CHARS_MODIFF
= MODIFF
;
1245 GAP_SIZE
-= outgoing_nbytes
;
1249 GPT_BYTE
+= outgoing_nbytes
;
1250 ZV_BYTE
+= outgoing_nbytes
;
1251 Z_BYTE
+= outgoing_nbytes
;
1252 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1257 /* The insert may have been in the unchanged region, so check again. */
1258 if (Z
- GPT
< END_UNCHANGED
)
1259 END_UNCHANGED
= Z
- GPT
;
1261 adjust_overlays_for_insert (PT
, nchars
);
1262 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1263 PT_BYTE
+ outgoing_nbytes
,
1266 if (BUF_INTERVALS (current_buffer
) != 0)
1267 offset_intervals (current_buffer
, PT
, nchars
);
1269 /* Get the intervals for the part of the string we are inserting. */
1270 intervals
= BUF_INTERVALS (buf
);
1271 if (nchars
< BUF_Z (buf
) - BUF_BEG (buf
))
1273 if (buf
== current_buffer
&& PT
<= from
)
1275 intervals
= copy_intervals (intervals
, from
, nchars
);
1278 /* Insert those intervals. */
1279 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1281 adjust_point (nchars
, outgoing_nbytes
);
1284 /* Record undo information and adjust markers and position keepers for
1285 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1286 chars (LEN_BYTE bytes) which resides in the gap just after
1289 PREV_TEXT nil means the new text was just inserted. */
1292 adjust_after_replace (EMACS_INT from
, EMACS_INT from_byte
,
1293 Lisp_Object prev_text
, EMACS_INT len
, EMACS_INT len_byte
)
1295 EMACS_INT nchars_del
= 0, nbytes_del
= 0;
1297 #ifdef BYTE_COMBINING_DEBUG
1298 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1299 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1303 if (STRINGP (prev_text
))
1305 nchars_del
= SCHARS (prev_text
);
1306 nbytes_del
= SBYTES (prev_text
);
1309 /* Update various buffer positions for the new text. */
1310 GAP_SIZE
-= len_byte
;
1312 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1313 GPT
+= len
; GPT_BYTE
+= len_byte
;
1314 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1317 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1320 adjust_markers_for_insert (from
, from_byte
,
1321 from
+ len
, from_byte
+ len_byte
, 0);
1323 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1326 record_delete (from
, prev_text
);
1327 record_insert (from
, len
);
1330 if (len
> nchars_del
)
1331 adjust_overlays_for_insert (from
, len
- nchars_del
);
1332 else if (len
< nchars_del
)
1333 adjust_overlays_for_delete (from
, nchars_del
- len
);
1334 if (BUF_INTERVALS (current_buffer
) != 0)
1336 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1340 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1342 /* As byte combining will decrease Z, we must check this again. */
1343 if (Z
- GPT
< END_UNCHANGED
)
1344 END_UNCHANGED
= Z
- GPT
;
1349 evaporate_overlays (from
);
1351 CHARS_MODIFF
= MODIFF
;
1354 /* Like adjust_after_replace, but doesn't require PREV_TEXT.
1355 This is for use when undo is not enabled in the current buffer. */
1358 adjust_after_replace_noundo (EMACS_INT from
, EMACS_INT from_byte
,
1359 EMACS_INT nchars_del
, EMACS_INT nbytes_del
,
1360 EMACS_INT len
, EMACS_INT len_byte
)
1362 #ifdef BYTE_COMBINING_DEBUG
1363 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1364 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1368 /* Update various buffer positions for the new text. */
1369 GAP_SIZE
-= len_byte
;
1371 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1372 GPT
+= len
; GPT_BYTE
+= len_byte
;
1373 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1376 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1379 adjust_markers_for_insert (from
, from_byte
,
1380 from
+ len
, from_byte
+ len_byte
, 0);
1382 if (len
> nchars_del
)
1383 adjust_overlays_for_insert (from
, len
- nchars_del
);
1384 else if (len
< nchars_del
)
1385 adjust_overlays_for_delete (from
, nchars_del
- len
);
1386 if (BUF_INTERVALS (current_buffer
) != 0)
1388 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1392 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1394 /* As byte combining will decrease Z, we must check this again. */
1395 if (Z
- GPT
< END_UNCHANGED
)
1396 END_UNCHANGED
= Z
- GPT
;
1401 evaporate_overlays (from
);
1403 CHARS_MODIFF
= MODIFF
;
1406 /* Record undo information, adjust markers and position keepers for an
1407 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1408 text already exists in the current buffer but character length (TO
1409 - FROM) may be incorrect, the correct length is NEWLEN. */
1412 adjust_after_insert (EMACS_INT from
, EMACS_INT from_byte
,
1413 EMACS_INT to
, EMACS_INT to_byte
, EMACS_INT newlen
)
1415 EMACS_INT len
= to
- from
, len_byte
= to_byte
- from_byte
;
1418 move_gap_both (to
, to_byte
);
1419 GAP_SIZE
+= len_byte
;
1420 GPT
-= len
; GPT_BYTE
-= len_byte
;
1421 ZV
-= len
; ZV_BYTE
-= len_byte
;
1422 Z
-= len
; Z_BYTE
-= len_byte
;
1423 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1426 /* Replace the text from character positions FROM to TO with NEW,
1427 If PREPARE is nonzero, call prepare_to_modify_buffer.
1428 If INHERIT, the newly inserted text should inherit text properties
1429 from the surrounding non-deleted text. */
1431 /* Note that this does not yet handle markers quite right.
1432 Also it needs to record a single undo-entry that does a replacement
1433 rather than a separate delete and insert.
1434 That way, undo will also handle markers properly.
1436 But if MARKERS is 0, don't relocate markers. */
1439 replace_range (EMACS_INT from
, EMACS_INT to
, Lisp_Object
new,
1440 int prepare
, int inherit
, int markers
)
1442 EMACS_INT inschars
= SCHARS (new);
1443 EMACS_INT insbytes
= SBYTES (new);
1444 EMACS_INT from_byte
, to_byte
;
1445 EMACS_INT nbytes_del
, nchars_del
;
1446 register Lisp_Object temp
;
1447 struct gcpro gcpro1
;
1449 EMACS_INT outgoing_insbytes
= insbytes
;
1450 Lisp_Object deletion
;
1459 EMACS_INT range_length
= to
- from
;
1460 prepare_to_modify_buffer (from
, to
, &from
);
1461 to
= from
+ range_length
;
1466 /* Make args be valid */
1472 from_byte
= CHAR_TO_BYTE (from
);
1473 to_byte
= CHAR_TO_BYTE (to
);
1475 nchars_del
= to
- from
;
1476 nbytes_del
= to_byte
- from_byte
;
1478 if (nbytes_del
<= 0 && insbytes
== 0)
1481 /* Make OUTGOING_INSBYTES describe the text
1482 as it will be inserted in this buffer. */
1484 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1485 outgoing_insbytes
= inschars
;
1486 else if (! STRING_MULTIBYTE (new))
1488 = count_size_as_multibyte (SDATA (new), insbytes
);
1490 /* Make sure point-max won't overflow after this insertion. */
1491 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1492 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1493 error ("Maximum buffer size exceeded");
1497 /* Make sure the gap is somewhere in or next to what we are deleting. */
1499 gap_right (from
, from_byte
);
1501 gap_left (to
, to_byte
, 0);
1503 /* Even if we don't record for undo, we must keep the original text
1504 because we may have to recover it because of inappropriate byte
1506 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1507 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1509 GAP_SIZE
+= nbytes_del
;
1512 ZV_BYTE
-= nbytes_del
;
1513 Z_BYTE
-= nbytes_del
;
1515 GPT_BYTE
= from_byte
;
1516 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1521 if (GPT
- BEG
< BEG_UNCHANGED
)
1522 BEG_UNCHANGED
= GPT
- BEG
;
1523 if (Z
- GPT
< END_UNCHANGED
)
1524 END_UNCHANGED
= Z
- GPT
;
1526 if (GAP_SIZE
< insbytes
)
1527 make_gap (insbytes
- GAP_SIZE
);
1529 /* Copy the string text into the buffer, perhaps converting
1530 between single-byte and multibyte. */
1531 copy_text (SDATA (new), GPT_ADDR
, insbytes
,
1532 STRING_MULTIBYTE (new),
1533 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1535 #ifdef BYTE_COMBINING_DEBUG
1536 /* We have copied text into the gap, but we have not marked
1537 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1538 here, for both the previous text and the following text.
1539 Meanwhile, GPT_ADDR does point to
1540 the text that has been stored by copy_text. */
1541 if (count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
)
1542 || count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
))
1546 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1548 /* Record the insertion first, so that when we undo,
1549 the deletion will be undone first. Thus, undo
1550 will insert before deleting, and thus will keep
1551 the markers before and after this text separate. */
1552 record_insert (from
+ SCHARS (deletion
), inschars
);
1553 record_delete (from
, deletion
);
1556 GAP_SIZE
-= outgoing_insbytes
;
1560 GPT_BYTE
+= outgoing_insbytes
;
1561 ZV_BYTE
+= outgoing_insbytes
;
1562 Z_BYTE
+= outgoing_insbytes
;
1563 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1568 /* Adjust the overlay center as needed. This must be done after
1569 adjusting the markers that bound the overlays. */
1570 adjust_overlays_for_delete (from
, nchars_del
);
1571 adjust_overlays_for_insert (from
, inschars
);
1573 /* Adjust markers for the deletion and the insertion. */
1575 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1576 inschars
, outgoing_insbytes
);
1578 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1580 /* Get the intervals for the part of the string we are inserting--
1581 not including the combined-before bytes. */
1582 intervals
= STRING_INTERVALS (new);
1583 /* Insert those intervals. */
1584 graft_intervals_into_buffer (intervals
, from
, inschars
,
1585 current_buffer
, inherit
);
1587 /* Relocate point as if it were a marker. */
1589 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1590 (from_byte
+ outgoing_insbytes
1591 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1593 if (outgoing_insbytes
== 0)
1594 evaporate_overlays (from
);
1599 CHARS_MODIFF
= MODIFF
;
1602 signal_after_change (from
, nchars_del
, GPT
- from
);
1603 update_compositions (from
, GPT
, CHECK_BORDER
);
1606 /* Replace the text from character positions FROM to TO with
1607 the text in INS of length INSCHARS.
1608 Keep the text properties that applied to the old characters
1609 (extending them to all the new chars if there are more new chars).
1611 Note that this does not yet handle markers quite right.
1613 If MARKERS is nonzero, relocate markers.
1615 Unlike most functions at this level, never call
1616 prepare_to_modify_buffer and never call signal_after_change. */
1619 replace_range_2 (EMACS_INT from
, EMACS_INT from_byte
,
1620 EMACS_INT to
, EMACS_INT to_byte
,
1621 const char *ins
, EMACS_INT inschars
, EMACS_INT insbytes
,
1624 EMACS_INT nbytes_del
, nchars_del
;
1629 nchars_del
= to
- from
;
1630 nbytes_del
= to_byte
- from_byte
;
1632 if (nbytes_del
<= 0 && insbytes
== 0)
1635 /* Make sure point-max won't overflow after this insertion. */
1636 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1637 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1638 error ("Maximum buffer size exceeded");
1640 /* Make sure the gap is somewhere in or next to what we are deleting. */
1642 gap_right (from
, from_byte
);
1644 gap_left (to
, to_byte
, 0);
1646 GAP_SIZE
+= nbytes_del
;
1649 ZV_BYTE
-= nbytes_del
;
1650 Z_BYTE
-= nbytes_del
;
1652 GPT_BYTE
= from_byte
;
1653 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1658 if (GPT
- BEG
< BEG_UNCHANGED
)
1659 BEG_UNCHANGED
= GPT
- BEG
;
1660 if (Z
- GPT
< END_UNCHANGED
)
1661 END_UNCHANGED
= Z
- GPT
;
1663 if (GAP_SIZE
< insbytes
)
1664 make_gap (insbytes
- GAP_SIZE
);
1666 /* Copy the replacement text into the buffer. */
1667 memcpy (GPT_ADDR
, ins
, insbytes
);
1669 #ifdef BYTE_COMBINING_DEBUG
1670 /* We have copied text into the gap, but we have not marked
1671 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1672 here, for both the previous text and the following text.
1673 Meanwhile, GPT_ADDR does point to
1674 the text that has been stored by copy_text. */
1675 if (count_combining_before (GPT_ADDR
, insbytes
, from
, from_byte
)
1676 || count_combining_after (GPT_ADDR
, insbytes
, from
, from_byte
))
1680 GAP_SIZE
-= insbytes
;
1684 GPT_BYTE
+= insbytes
;
1685 ZV_BYTE
+= insbytes
;
1687 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1692 /* Adjust the overlay center as needed. This must be done after
1693 adjusting the markers that bound the overlays. */
1694 if (nchars_del
!= inschars
)
1696 adjust_overlays_for_insert (from
, inschars
);
1697 adjust_overlays_for_delete (from
+ inschars
, nchars_del
);
1700 /* Adjust markers for the deletion and the insertion. */
1702 && ! (nchars_del
== 1 && inschars
== 1 && nbytes_del
== insbytes
))
1703 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1704 inschars
, insbytes
);
1706 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1708 /* Relocate point as if it were a marker. */
1709 if (from
< PT
&& (nchars_del
!= inschars
|| nbytes_del
!= insbytes
))
1712 /* PT was within the deleted text. Move it to FROM. */
1713 adjust_point (from
- PT
, from_byte
- PT_BYTE
);
1715 adjust_point (inschars
- nchars_del
, insbytes
- nbytes_del
);
1719 evaporate_overlays (from
);
1724 CHARS_MODIFF
= MODIFF
;
1727 /* Delete characters in current buffer
1728 from FROM up to (but not including) TO.
1729 If TO comes before FROM, we delete nothing. */
1732 del_range (EMACS_INT from
, EMACS_INT to
)
1734 del_range_1 (from
, to
, 1, 0);
1737 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1738 RET_STRING says to return the deleted text. */
1741 del_range_1 (EMACS_INT from
, EMACS_INT to
, int prepare
, int ret_string
)
1743 EMACS_INT from_byte
, to_byte
;
1744 Lisp_Object deletion
;
1745 struct gcpro gcpro1
;
1747 /* Make args be valid */
1758 EMACS_INT range_length
= to
- from
;
1759 prepare_to_modify_buffer (from
, to
, &from
);
1760 to
= min (ZV
, from
+ range_length
);
1763 from_byte
= CHAR_TO_BYTE (from
);
1764 to_byte
= CHAR_TO_BYTE (to
);
1766 deletion
= del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
);
1768 signal_after_change (from
, to
- from
, 0);
1769 update_compositions (from
, from
, CHECK_HEAD
);
1774 /* Like del_range_1 but args are byte positions, not char positions. */
1777 del_range_byte (EMACS_INT from_byte
, EMACS_INT to_byte
, int prepare
)
1781 /* Make args be valid */
1782 if (from_byte
< BEGV_BYTE
)
1783 from_byte
= BEGV_BYTE
;
1784 if (to_byte
> ZV_BYTE
)
1787 if (to_byte
<= from_byte
)
1790 from
= BYTE_TO_CHAR (from_byte
);
1791 to
= BYTE_TO_CHAR (to_byte
);
1795 EMACS_INT old_from
= from
, old_to
= Z
- to
;
1796 EMACS_INT range_length
= to
- from
;
1797 prepare_to_modify_buffer (from
, to
, &from
);
1798 to
= from
+ range_length
;
1800 if (old_from
!= from
)
1801 from_byte
= CHAR_TO_BYTE (from
);
1807 else if (old_to
== Z
- to
)
1808 to_byte
= CHAR_TO_BYTE (to
);
1811 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1812 signal_after_change (from
, to
- from
, 0);
1813 update_compositions (from
, from
, CHECK_HEAD
);
1816 /* Like del_range_1, but positions are specified both as charpos
1820 del_range_both (EMACS_INT from
, EMACS_INT from_byte
,
1821 EMACS_INT to
, EMACS_INT to_byte
, int prepare
)
1823 /* Make args be valid */
1824 if (from_byte
< BEGV_BYTE
)
1825 from_byte
= BEGV_BYTE
;
1826 if (to_byte
> ZV_BYTE
)
1829 if (to_byte
<= from_byte
)
1839 EMACS_INT old_from
= from
, old_to
= Z
- to
;
1840 EMACS_INT range_length
= to
- from
;
1841 prepare_to_modify_buffer (from
, to
, &from
);
1842 to
= from
+ range_length
;
1844 if (old_from
!= from
)
1845 from_byte
= CHAR_TO_BYTE (from
);
1851 else if (old_to
== Z
- to
)
1852 to_byte
= CHAR_TO_BYTE (to
);
1855 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1856 signal_after_change (from
, to
- from
, 0);
1857 update_compositions (from
, from
, CHECK_HEAD
);
1860 /* Delete a range of text, specified both as character positions
1861 and byte positions. FROM and TO are character positions,
1862 while FROM_BYTE and TO_BYTE are byte positions.
1863 If RET_STRING is true, the deleted area is returned as a string. */
1866 del_range_2 (EMACS_INT from
, EMACS_INT from_byte
,
1867 EMACS_INT to
, EMACS_INT to_byte
, int ret_string
)
1869 register EMACS_INT nbytes_del
, nchars_del
;
1870 Lisp_Object deletion
;
1874 nchars_del
= to
- from
;
1875 nbytes_del
= to_byte
- from_byte
;
1877 /* Make sure the gap is somewhere in or next to what we are deleting. */
1879 gap_right (from
, from_byte
);
1881 gap_left (to
, to_byte
, 0);
1883 #ifdef BYTE_COMBINING_DEBUG
1884 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
1885 Z_BYTE
- to_byte
, from
, from_byte
))
1889 if (ret_string
|| ! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1890 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1894 /* Relocate all markers pointing into the new, larger gap
1895 to point at the end of the text before the gap.
1896 Do this before recording the deletion,
1897 so that undo handles this after reinserting the text. */
1898 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1900 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1901 record_delete (from
, deletion
);
1903 CHARS_MODIFF
= MODIFF
;
1905 /* Relocate point as if it were a marker. */
1907 adjust_point (from
- (PT
< to
? PT
: to
),
1908 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
1910 offset_intervals (current_buffer
, from
, - nchars_del
);
1912 /* Adjust the overlay center as needed. This must be done after
1913 adjusting the markers that bound the overlays. */
1914 adjust_overlays_for_delete (from
, nchars_del
);
1916 GAP_SIZE
+= nbytes_del
;
1917 ZV_BYTE
-= nbytes_del
;
1918 Z_BYTE
-= nbytes_del
;
1922 GPT_BYTE
= from_byte
;
1923 if (GAP_SIZE
> 0 && !current_buffer
->text
->inhibit_shrinking
)
1924 /* Put an anchor, unless called from decode_coding_object which
1925 needs to access the previous gap contents. */
1931 if (GPT
- BEG
< BEG_UNCHANGED
)
1932 BEG_UNCHANGED
= GPT
- BEG
;
1933 if (Z
- GPT
< END_UNCHANGED
)
1934 END_UNCHANGED
= Z
- GPT
;
1938 evaporate_overlays (from
);
1943 /* Call this if you're about to change the region of BUFFER from
1944 character positions START to END. This checks the read-only
1945 properties of the region, calls the necessary modification hooks,
1946 and warns the next redisplay that it should pay attention to that
1949 If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
1950 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1953 modify_region (struct buffer
*buffer
, EMACS_INT start
, EMACS_INT end
,
1954 int preserve_chars_modiff
)
1956 struct buffer
*old_buffer
= current_buffer
;
1958 if (buffer
!= old_buffer
)
1959 set_buffer_internal (buffer
);
1961 prepare_to_modify_buffer (start
, end
, NULL
);
1963 BUF_COMPUTE_UNCHANGED (buffer
, start
- 1, end
);
1965 if (MODIFF
<= SAVE_MODIFF
)
1966 record_first_change ();
1968 if (! preserve_chars_modiff
)
1969 CHARS_MODIFF
= MODIFF
;
1971 BVAR (buffer
, point_before_scroll
) = Qnil
;
1973 if (buffer
!= old_buffer
)
1974 set_buffer_internal (old_buffer
);
1977 /* Check that it is okay to modify the buffer between START and END,
1978 which are char positions.
1980 Run the before-change-function, if any. If intervals are in use,
1981 verify that the text to be modified is not read-only, and call
1982 any modification properties the text may have.
1984 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1985 by holding its value temporarily in a marker. */
1988 prepare_to_modify_buffer (EMACS_INT start
, EMACS_INT end
,
1989 EMACS_INT
*preserve_ptr
)
1991 struct buffer
*base_buffer
;
1993 if (!NILP (BVAR (current_buffer
, read_only
)))
1994 Fbarf_if_buffer_read_only ();
1996 /* Let redisplay consider other windows than selected_window
1997 if modifying another buffer. */
1998 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
1999 ++windows_or_buffers_changed
;
2001 if (BUF_INTERVALS (current_buffer
) != 0)
2005 Lisp_Object preserve_marker
;
2006 struct gcpro gcpro1
;
2007 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
2008 GCPRO1 (preserve_marker
);
2009 verify_interval_modification (current_buffer
, start
, end
);
2010 *preserve_ptr
= marker_position (preserve_marker
);
2011 unchain_marker (XMARKER (preserve_marker
));
2015 verify_interval_modification (current_buffer
, start
, end
);
2018 /* For indirect buffers, use the base buffer to check clashes. */
2019 if (current_buffer
->base_buffer
!= 0)
2020 base_buffer
= current_buffer
->base_buffer
;
2022 base_buffer
= current_buffer
;
2024 #ifdef CLASH_DETECTION
2025 if (!NILP (BVAR (base_buffer
, file_truename
))
2026 /* Make binding buffer-file-name to nil effective. */
2027 && !NILP (BVAR (base_buffer
, filename
))
2028 && SAVE_MODIFF
>= MODIFF
)
2029 lock_file (BVAR (base_buffer
, file_truename
));
2031 /* At least warn if this file has changed on disk since it was visited. */
2032 if (!NILP (BVAR (base_buffer
, filename
))
2033 && SAVE_MODIFF
>= MODIFF
2034 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2035 && !NILP (Ffile_exists_p (BVAR (base_buffer
, filename
))))
2036 call1 (intern ("ask-user-about-supersession-threat"),
2037 BVAR (base_buffer
,filename
));
2038 #endif /* not CLASH_DETECTION */
2040 /* If `select-active-regions' is non-nil, save the region text. */
2041 if (!NILP (BVAR (current_buffer
, mark_active
))
2042 && !inhibit_modification_hooks
2043 && XMARKER (BVAR (current_buffer
, mark
))->buffer
2044 && NILP (Vsaved_region_selection
)
2045 && (EQ (Vselect_active_regions
, Qonly
)
2046 ? EQ (CAR_SAFE (Vtransient_mark_mode
), Qonly
)
2047 : (!NILP (Vselect_active_regions
)
2048 && !NILP (Vtransient_mark_mode
))))
2050 EMACS_INT b
= XMARKER (BVAR (current_buffer
, mark
))->charpos
;
2053 Vsaved_region_selection
= make_buffer_string (b
, e
, 0);
2055 Vsaved_region_selection
= make_buffer_string (e
, b
, 0);
2058 signal_before_change (start
, end
, preserve_ptr
);
2060 if (current_buffer
->newline_cache
)
2061 invalidate_region_cache (current_buffer
,
2062 current_buffer
->newline_cache
,
2063 start
- BEG
, Z
- end
);
2064 if (current_buffer
->width_run_cache
)
2065 invalidate_region_cache (current_buffer
,
2066 current_buffer
->width_run_cache
,
2067 start
- BEG
, Z
- end
);
2069 Vdeactivate_mark
= Qt
;
2072 /* These macros work with an argument named `preserve_ptr'
2073 and a local variable named `preserve_marker'. */
2075 #define PRESERVE_VALUE \
2076 if (preserve_ptr && NILP (preserve_marker)) \
2077 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2079 #define RESTORE_VALUE \
2080 if (! NILP (preserve_marker)) \
2082 *preserve_ptr = marker_position (preserve_marker); \
2083 unchain_marker (XMARKER (preserve_marker)); \
2086 #define PRESERVE_START_END \
2087 if (NILP (start_marker)) \
2088 start_marker = Fcopy_marker (start, Qnil); \
2089 if (NILP (end_marker)) \
2090 end_marker = Fcopy_marker (end, Qnil);
2092 #define FETCH_START \
2093 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2096 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2098 /* Set a variable to nil if an error occurred.
2099 Don't change the variable if there was no error.
2100 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
2101 VARIABLE is the variable to maybe set to nil.
2102 NO-ERROR-FLAG is nil if there was an error,
2103 anything else meaning no error (so this function does nothing). */
2105 reset_var_on_error (Lisp_Object val
)
2107 if (NILP (XCDR (val
)))
2108 Fset (XCAR (val
), Qnil
);
2112 /* Signal a change to the buffer immediately before it happens.
2113 START_INT and END_INT are the bounds of the text to be changed.
2115 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2116 by holding its value temporarily in a marker. */
2119 signal_before_change (EMACS_INT start_int
, EMACS_INT end_int
,
2120 EMACS_INT
*preserve_ptr
)
2122 Lisp_Object start
, end
;
2123 Lisp_Object start_marker
, end_marker
;
2124 Lisp_Object preserve_marker
;
2125 struct gcpro gcpro1
, gcpro2
, gcpro3
;
2126 int count
= SPECPDL_INDEX ();
2128 if (inhibit_modification_hooks
)
2131 start
= make_number (start_int
);
2132 end
= make_number (end_int
);
2133 preserve_marker
= Qnil
;
2134 start_marker
= Qnil
;
2136 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
2138 specbind (Qinhibit_modification_hooks
, Qt
);
2140 /* If buffer is unmodified, run a special hook for that case. */
2141 if (SAVE_MODIFF
>= MODIFF
2142 && !NILP (Vfirst_change_hook
)
2143 && !NILP (Vrun_hooks
))
2147 call1 (Vrun_hooks
, Qfirst_change_hook
);
2150 /* Now run the before-change-functions if any. */
2151 if (!NILP (Vbefore_change_functions
))
2153 Lisp_Object args
[3];
2154 Lisp_Object rvoe_arg
= Fcons (Qbefore_change_functions
, Qnil
);
2159 /* Mark before-change-functions to be reset to nil in case of error. */
2160 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2162 /* Actually run the hook functions. */
2163 args
[0] = Qbefore_change_functions
;
2164 args
[1] = FETCH_START
;
2165 args
[2] = FETCH_END
;
2166 Frun_hook_with_args (3, args
);
2168 /* There was no error: unarm the reset_on_error. */
2169 XSETCDR (rvoe_arg
, Qt
);
2172 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2175 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2176 FETCH_START
, FETCH_END
, Qnil
);
2179 if (! NILP (start_marker
))
2180 free_marker (start_marker
);
2181 if (! NILP (end_marker
))
2182 free_marker (end_marker
);
2186 unbind_to (count
, Qnil
);
2189 /* Signal a change immediately after it happens.
2190 CHARPOS is the character position of the start of the changed text.
2191 LENDEL is the number of characters of the text before the change.
2192 (Not the whole buffer; just the part that was changed.)
2193 LENINS is the number of characters in that part of the text
2194 after the change. */
2197 signal_after_change (EMACS_INT charpos
, EMACS_INT lendel
, EMACS_INT lenins
)
2199 int count
= SPECPDL_INDEX ();
2200 if (inhibit_modification_hooks
)
2203 /* If we are deferring calls to the after-change functions
2204 and there are no before-change functions,
2205 just record the args that we were going to use. */
2206 if (! NILP (Vcombine_after_change_calls
)
2207 && NILP (Vbefore_change_functions
)
2208 && !current_buffer
->overlays_before
2209 && !current_buffer
->overlays_after
)
2213 if (!NILP (combine_after_change_list
)
2214 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2215 Fcombine_after_change_execute ();
2217 elt
= Fcons (make_number (charpos
- BEG
),
2218 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2219 Fcons (make_number (lenins
- lendel
), Qnil
)));
2220 combine_after_change_list
2221 = Fcons (elt
, combine_after_change_list
);
2222 combine_after_change_buffer
= Fcurrent_buffer ();
2227 if (!NILP (combine_after_change_list
))
2228 Fcombine_after_change_execute ();
2230 specbind (Qinhibit_modification_hooks
, Qt
);
2232 if (!NILP (Vafter_change_functions
))
2234 Lisp_Object args
[4];
2235 Lisp_Object rvoe_arg
= Fcons (Qafter_change_functions
, Qnil
);
2237 /* Mark after-change-functions to be reset to nil in case of error. */
2238 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2240 /* Actually run the hook functions. */
2241 args
[0] = Qafter_change_functions
;
2242 XSETFASTINT (args
[1], charpos
);
2243 XSETFASTINT (args
[2], charpos
+ lenins
);
2244 XSETFASTINT (args
[3], lendel
);
2245 Frun_hook_with_args (4, args
);
2247 /* There was no error: unarm the reset_on_error. */
2248 XSETCDR (rvoe_arg
, Qt
);
2251 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2252 report_overlay_modification (make_number (charpos
),
2253 make_number (charpos
+ lenins
),
2255 make_number (charpos
),
2256 make_number (charpos
+ lenins
),
2257 make_number (lendel
));
2259 /* After an insertion, call the text properties
2260 insert-behind-hooks or insert-in-front-hooks. */
2262 report_interval_modification (make_number (charpos
),
2263 make_number (charpos
+ lenins
));
2265 unbind_to (count
, Qnil
);
2269 Fcombine_after_change_execute_1 (Lisp_Object val
)
2271 Vcombine_after_change_calls
= val
;
2275 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2276 Scombine_after_change_execute
, 0, 0, 0,
2277 doc
: /* This function is for use internally in `combine-after-change-calls'. */)
2280 int count
= SPECPDL_INDEX ();
2281 EMACS_INT beg
, end
, change
;
2282 EMACS_INT begpos
, endpos
;
2285 if (NILP (combine_after_change_list
))
2288 /* It is rare for combine_after_change_buffer to be invalid, but
2289 possible. It can happen when combine-after-change-calls is
2290 non-nil, and insertion calls a file handler (e.g. through
2291 lock_file) which scribbles into a temp file -- cyd */
2292 if (!BUFFERP (combine_after_change_buffer
)
2293 || NILP (BVAR (XBUFFER (combine_after_change_buffer
), name
)))
2295 combine_after_change_list
= Qnil
;
2299 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2301 Fset_buffer (combine_after_change_buffer
);
2303 /* # chars unchanged at beginning of buffer. */
2305 /* # chars unchanged at end of buffer. */
2307 /* Total amount of insertion (negative for deletion). */
2310 /* Scan the various individual changes,
2311 accumulating the range info in BEG, END and CHANGE. */
2312 for (tail
= combine_after_change_list
; CONSP (tail
);
2316 EMACS_INT thisbeg
, thisend
, thischange
;
2318 /* Extract the info from the next element. */
2322 thisbeg
= XINT (XCAR (elt
));
2327 thisend
= XINT (XCAR (elt
));
2332 thischange
= XINT (XCAR (elt
));
2334 /* Merge this range into the accumulated range. */
2335 change
+= thischange
;
2342 /* Get the current start and end positions of the range
2343 that was changed. */
2347 /* We are about to handle these, so discard them. */
2348 combine_after_change_list
= Qnil
;
2350 /* Now run the after-change functions for real.
2351 Turn off the flag that defers them. */
2352 record_unwind_protect (Fcombine_after_change_execute_1
,
2353 Vcombine_after_change_calls
);
2354 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2355 update_compositions (begpos
, endpos
, CHECK_ALL
);
2357 return unbind_to (count
, Qnil
);
2361 syms_of_insdel (void)
2363 staticpro (&combine_after_change_list
);
2364 staticpro (&combine_after_change_buffer
);
2365 combine_after_change_list
= Qnil
;
2366 combine_after_change_buffer
= Qnil
;
2368 DEFVAR_BOOL ("check-markers-debug-flag", check_markers_debug_flag
,
2369 doc
: /* Non-nil means enable debugging checks for invalid marker positions. */);
2370 check_markers_debug_flag
= 0;
2371 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls
,
2372 doc
: /* Used internally by the `combine-after-change-calls' macro. */);
2373 Vcombine_after_change_calls
= Qnil
;
2375 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks
,
2376 doc
: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2377 This affects `before-change-functions' and `after-change-functions',
2378 as well as hooks attached to text properties and overlays. */);
2379 inhibit_modification_hooks
= 0;
2380 Qinhibit_modification_hooks
= intern_c_string ("inhibit-modification-hooks");
2381 staticpro (&Qinhibit_modification_hooks
);
2383 defsubr (&Scombine_after_change_execute
);