1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
25 #include "intervals.h"
27 #include "character.h"
29 #include "blockinput.h"
30 #include "region-cache.h"
36 static void insert_from_string_1 (Lisp_Object string
,
37 EMACS_INT pos
, EMACS_INT pos_byte
,
38 EMACS_INT nchars
, EMACS_INT nbytes
,
39 int inherit
, int before_markers
);
40 static void insert_from_buffer_1 (struct buffer
*buf
,
41 EMACS_INT from
, EMACS_INT nchars
,
43 static void gap_left (EMACS_INT charpos
, EMACS_INT bytepos
, int newgap
);
44 static void gap_right (EMACS_INT charpos
, EMACS_INT bytepos
);
45 static void adjust_markers_gap_motion (EMACS_INT from
, EMACS_INT to
,
47 static void adjust_markers_for_insert (EMACS_INT from
, EMACS_INT from_byte
,
48 EMACS_INT to
, EMACS_INT to_byte
,
50 static void adjust_markers_for_replace (EMACS_INT
, EMACS_INT
, EMACS_INT
,
51 EMACS_INT
, EMACS_INT
, EMACS_INT
);
52 static void adjust_point (EMACS_INT nchars
, EMACS_INT nbytes
);
54 Lisp_Object
Fcombine_after_change_execute ();
56 /* Non-nil means don't call the after-change-functions right away,
57 just record an element in Vcombine_after_change_calls_list. */
58 Lisp_Object Vcombine_after_change_calls
;
60 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
61 describing changes which happened while combine_after_change_calls
62 was nonzero. We use this to decide how to call them
63 once the deferral ends.
66 BEG-UNCHANGED is the number of chars before the changed range.
67 END-UNCHANGED is the number of chars after the changed range,
68 and CHANGE-AMOUNT is the number of characters inserted by the change
69 (negative for a deletion). */
70 Lisp_Object combine_after_change_list
;
72 /* Buffer which combine_after_change_list is about. */
73 Lisp_Object combine_after_change_buffer
;
75 Lisp_Object Qinhibit_modification_hooks
;
78 /* Check all markers in the current buffer, looking for something invalid. */
80 static int check_markers_debug_flag
;
82 #define CHECK_MARKERS() \
83 if (check_markers_debug_flag) \
90 register struct Lisp_Marker
*tail
;
91 int multibyte
= ! NILP (current_buffer
->enable_multibyte_characters
);
93 for (tail
= BUF_MARKERS (current_buffer
); tail
; tail
= tail
->next
)
95 if (tail
->buffer
->text
!= current_buffer
->text
)
97 if (tail
->charpos
> Z
)
99 if (tail
->bytepos
> Z_BYTE
)
101 if (multibyte
&& ! CHAR_HEAD_P (FETCH_BYTE (tail
->bytepos
)))
106 /* Move gap to position CHARPOS.
107 Note that this can quit! */
110 move_gap (EMACS_INT charpos
)
112 move_gap_both (charpos
, charpos_to_bytepos (charpos
));
115 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
116 Note that this can quit! */
119 move_gap_both (EMACS_INT charpos
, EMACS_INT bytepos
)
121 if (bytepos
< GPT_BYTE
)
122 gap_left (charpos
, bytepos
, 0);
123 else if (bytepos
> GPT_BYTE
)
124 gap_right (charpos
, bytepos
);
127 /* Move the gap to a position less than the current GPT.
128 BYTEPOS describes the new position as a byte position,
129 and CHARPOS is the corresponding char position.
130 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
133 gap_left (EMACS_INT charpos
, EMACS_INT bytepos
, int newgap
)
135 register unsigned char *to
, *from
;
136 register EMACS_INT i
;
140 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
147 /* Now copy the characters. To move the gap down,
148 copy characters up. */
152 /* I gets number of characters left to copy. */
153 i
= new_s1
- bytepos
;
156 /* If a quit is requested, stop copying now.
157 Change BYTEPOS to be where we have actually moved the gap to. */
161 charpos
= BYTE_TO_CHAR (bytepos
);
164 /* Move at most 32000 chars before checking again for a quit. */
169 /* bcopy is safe if the two areas of memory do not overlap
170 or on systems where bcopy is always safe for moving upward. */
171 && (BCOPY_UPWARD_SAFE
172 || to
- from
>= 128))
174 /* If overlap is not safe, avoid it by not moving too many
175 characters at once. */
176 if (!BCOPY_UPWARD_SAFE
&& i
> to
- from
)
191 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
192 BYTEPOS is where the loop above stopped, which may be what was specified
193 or may be where a quit was detected. */
194 adjust_markers_gap_motion (bytepos
, GPT_BYTE
, GAP_SIZE
);
197 if (bytepos
< charpos
)
199 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
203 /* Move the gap to a position greater than the current GPT.
204 BYTEPOS describes the new position as a byte position,
205 and CHARPOS is the corresponding char position. */
208 gap_right (EMACS_INT charpos
, EMACS_INT bytepos
)
210 register unsigned char *to
, *from
;
211 register EMACS_INT i
;
214 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
221 /* Now copy the characters. To move the gap up,
222 copy characters down. */
226 /* I gets number of characters left to copy. */
227 i
= bytepos
- new_s1
;
230 /* If a quit is requested, stop copying now.
231 Change BYTEPOS to be where we have actually moved the gap to. */
235 charpos
= BYTE_TO_CHAR (bytepos
);
238 /* Move at most 32000 chars before checking again for a quit. */
243 /* bcopy is safe if the two areas of memory do not overlap
244 or on systems where bcopy is always safe for moving downward. */
245 && (BCOPY_DOWNWARD_SAFE
246 || from
- to
>= 128))
248 /* If overlap is not safe, avoid it by not moving too many
249 characters at once. */
250 if (!BCOPY_DOWNWARD_SAFE
&& i
> from
- to
)
265 adjust_markers_gap_motion (GPT_BYTE
+ GAP_SIZE
, bytepos
+ GAP_SIZE
,
269 if (bytepos
< charpos
)
271 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
275 /* Add AMOUNT to the byte position of every marker in the current buffer
276 whose current byte position is between FROM (exclusive) and TO (inclusive).
278 Also, any markers past the outside of that interval, in the direction
279 of adjustment, are first moved back to the near end of the interval
280 and then adjusted by AMOUNT.
282 When the latter adjustment is done, if AMOUNT is negative,
283 we record the adjustment for undo. (This case happens only for
286 The markers' character positions are not altered,
287 because gap motion does not affect character positions. */
289 int adjust_markers_test
;
292 adjust_markers_gap_motion (EMACS_INT from
, EMACS_INT to
, EMACS_INT amount
)
294 /* Now that a marker has a bytepos, not counting the gap,
295 nothing needs to be done here. */
298 register struct Lisp_Marker
*m
;
299 register EMACS_INT mpos
;
301 marker
= BUF_MARKERS (current_buffer
);
303 while (!NILP (marker
))
305 m
= XMARKER (marker
);
309 if (mpos
> to
&& mpos
< to
+ amount
)
311 if (adjust_markers_test
)
318 /* Here's the case where a marker is inside text being deleted.
319 AMOUNT can be negative for gap motion, too,
320 but then this range contains no markers. */
321 if (mpos
> from
+ amount
&& mpos
<= from
)
323 if (adjust_markers_test
)
325 mpos
= from
+ amount
;
328 if (mpos
> from
&& mpos
<= to
)
336 /* Adjust all markers for a deletion
337 whose range in bytes is FROM_BYTE to TO_BYTE.
338 The range in charpos is FROM to TO.
340 This function assumes that the gap is adjacent to
341 or inside of the range being deleted. */
344 adjust_markers_for_delete (EMACS_INT from
, EMACS_INT from_byte
,
345 EMACS_INT to
, EMACS_INT to_byte
)
348 register struct Lisp_Marker
*m
;
349 register EMACS_INT charpos
;
351 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
353 charpos
= m
->charpos
;
358 /* If the marker is after the deletion,
359 relocate by number of chars / bytes deleted. */
362 m
->charpos
-= to
- from
;
363 m
->bytepos
-= to_byte
- from_byte
;
365 /* Here's the case where a marker is inside text being deleted. */
366 else if (charpos
> from
)
368 if (! m
->insertion_type
)
369 { /* Normal markers will end up at the beginning of the
370 re-inserted text after undoing a deletion, and must be
371 adjusted to move them to the correct place. */
372 XSETMISC (marker
, m
);
373 record_marker_adjustment (marker
, from
- charpos
);
375 else if (charpos
< to
)
376 { /* Before-insertion markers will automatically move forward
377 upon re-inserting the deleted text, so we have to arrange
378 for them to move backward to the correct position. */
379 XSETMISC (marker
, m
);
380 record_marker_adjustment (marker
, to
- charpos
);
383 m
->bytepos
= from_byte
;
385 /* Here's the case where a before-insertion marker is immediately
386 before the deleted region. */
387 else if (charpos
== from
&& m
->insertion_type
)
389 /* Undoing the change uses normal insertion, which will
390 incorrectly make MARKER move forward, so we arrange for it
391 to then move backward to the correct place at the beginning
392 of the deleted region. */
393 XSETMISC (marker
, m
);
394 record_marker_adjustment (marker
, to
- from
);
400 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
401 to TO / TO_BYTE. We have to relocate the charpos of every marker
402 that points after the insertion (but not their bytepos).
404 When a marker points at the insertion point,
405 we advance it if either its insertion-type is t
406 or BEFORE_MARKERS is true. */
409 adjust_markers_for_insert (EMACS_INT from
, EMACS_INT from_byte
,
410 EMACS_INT to
, EMACS_INT to_byte
, int before_markers
)
412 struct Lisp_Marker
*m
;
414 EMACS_INT nchars
= to
- from
;
415 EMACS_INT nbytes
= to_byte
- from_byte
;
417 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
419 eassert (m
->bytepos
>= m
->charpos
420 && m
->bytepos
- m
->charpos
<= Z_BYTE
- Z
);
422 if (m
->bytepos
== from_byte
)
424 if (m
->insertion_type
|| before_markers
)
426 m
->bytepos
= to_byte
;
428 if (m
->insertion_type
)
432 else if (m
->bytepos
> from_byte
)
434 m
->bytepos
+= nbytes
;
435 m
->charpos
+= nchars
;
439 /* Adjusting only markers whose insertion-type is t may result in
440 - disordered start and end in overlays, and
441 - disordered overlays in the slot `overlays_before' of current_buffer. */
444 fix_start_end_in_overlays(from
, to
);
445 fix_overlays_before (current_buffer
, from
, to
);
449 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
451 This is used only when the value of point changes due to an insert
452 or delete; it does not represent a conceptual change in point as a
453 marker. In particular, point is not crossing any interval
454 boundaries, so there's no need to use the usual SET_PT macro. In
455 fact it would be incorrect to do so, because either the old or the
456 new value of point is out of sync with the current set of
460 adjust_point (EMACS_INT nchars
, EMACS_INT nbytes
)
462 BUF_PT (current_buffer
) += nchars
;
463 BUF_PT_BYTE (current_buffer
) += nbytes
;
465 /* In a single-byte buffer, the two positions must be equal. */
466 eassert (PT_BYTE
>= PT
&& PT_BYTE
- PT
<= ZV_BYTE
- ZV
);
469 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
470 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
471 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
475 adjust_markers_for_replace (EMACS_INT from
, EMACS_INT from_byte
,
476 EMACS_INT old_chars
, EMACS_INT old_bytes
,
477 EMACS_INT new_chars
, EMACS_INT new_bytes
)
479 register struct Lisp_Marker
*m
;
480 EMACS_INT prev_to_byte
= from_byte
+ old_bytes
;
481 EMACS_INT diff_chars
= new_chars
- old_chars
;
482 EMACS_INT diff_bytes
= new_bytes
- old_bytes
;
484 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
486 if (m
->bytepos
>= prev_to_byte
)
488 m
->charpos
+= diff_chars
;
489 m
->bytepos
+= diff_bytes
;
491 else if (m
->bytepos
> from_byte
)
494 m
->bytepos
= from_byte
;
502 /* Make the gap NBYTES_ADDED bytes longer. */
505 make_gap_larger (EMACS_INT nbytes_added
)
508 EMACS_INT real_gap_loc
;
509 EMACS_INT real_gap_loc_byte
;
510 EMACS_INT old_gap_size
;
512 /* If we have to get more space, get enough to last a while. */
513 nbytes_added
+= 2000;
515 { EMACS_INT total_size
= Z_BYTE
- BEG_BYTE
+ GAP_SIZE
+ nbytes_added
;
517 /* Don't allow a buffer size that won't fit in a Lisp integer. */
518 || total_size
!= XINT (make_number (total_size
))
519 /* Don't allow a buffer size that won't fit in an int
520 even if it will fit in a Lisp integer.
521 That won't work because so many places still use `int'. */
522 || total_size
!= (EMACS_INT
) (int) total_size
)
523 error ("Buffer exceeds maximum size");
526 enlarge_buffer_text (current_buffer
, nbytes_added
);
528 /* Prevent quitting in move_gap. */
533 real_gap_loc_byte
= GPT_BYTE
;
534 old_gap_size
= GAP_SIZE
;
536 /* Call the newly allocated space a gap at the end of the whole space. */
538 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
539 GAP_SIZE
= nbytes_added
;
541 /* Move the new gap down to be consecutive with the end of the old one.
542 This adjusts the markers properly too. */
543 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
545 /* Now combine the two into one large gap. */
546 GAP_SIZE
+= old_gap_size
;
548 GPT_BYTE
= real_gap_loc_byte
;
557 /* Make the gap NBYTES_REMOVED bytes shorter. */
560 make_gap_smaller (EMACS_INT nbytes_removed
)
563 EMACS_INT real_gap_loc
;
564 EMACS_INT real_gap_loc_byte
;
566 EMACS_INT real_Z_byte
;
567 EMACS_INT real_beg_unchanged
;
568 EMACS_INT new_gap_size
;
570 /* Make sure the gap is at least 20 bytes. */
571 if (GAP_SIZE
- nbytes_removed
< 20)
572 nbytes_removed
= GAP_SIZE
- 20;
574 /* Prevent quitting in move_gap. */
579 real_gap_loc_byte
= GPT_BYTE
;
580 new_gap_size
= GAP_SIZE
- nbytes_removed
;
582 real_Z_byte
= Z_BYTE
;
583 real_beg_unchanged
= BEG_UNCHANGED
;
585 /* Pretend that the last unwanted part of the gap is the entire gap,
586 and that the first desired part of the gap is part of the buffer
588 bzero (GPT_ADDR
, new_gap_size
);
590 GPT_BYTE
+= new_gap_size
;
592 Z_BYTE
+= new_gap_size
;
593 GAP_SIZE
= nbytes_removed
;
595 /* Move the unwanted pretend gap to the end of the buffer. This
596 adjusts the markers properly too. */
597 gap_right (Z
, Z_BYTE
);
599 enlarge_buffer_text (current_buffer
, -nbytes_removed
);
601 /* Now restore the desired gap. */
602 GAP_SIZE
= new_gap_size
;
604 GPT_BYTE
= real_gap_loc_byte
;
606 Z_BYTE
= real_Z_byte
;
607 BEG_UNCHANGED
= real_beg_unchanged
;
616 make_gap (EMACS_INT nbytes_added
)
618 if (nbytes_added
>= 0)
619 make_gap_larger (nbytes_added
);
620 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
622 make_gap_smaller (-nbytes_added
);
626 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
627 FROM_MULTIBYTE says whether the incoming text is multibyte.
628 TO_MULTIBYTE says whether to store the text as multibyte.
629 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
631 Return the number of bytes stored at TO_ADDR. */
634 copy_text (const unsigned char *from_addr
, unsigned char *to_addr
,
635 EMACS_INT nbytes
, int from_multibyte
, int to_multibyte
)
637 if (from_multibyte
== to_multibyte
)
639 bcopy (from_addr
, to_addr
, nbytes
);
642 else if (from_multibyte
)
644 EMACS_INT nchars
= 0;
645 EMACS_INT bytes_left
= nbytes
;
646 Lisp_Object tbl
= Qnil
;
648 while (bytes_left
> 0)
651 c
= STRING_CHAR_AND_LENGTH (from_addr
, thislen
);
652 if (! ASCII_CHAR_P (c
))
655 from_addr
+= thislen
;
656 bytes_left
-= thislen
;
663 unsigned char *initial_to_addr
= to_addr
;
665 /* Convert single-byte to multibyte. */
668 int c
= *from_addr
++;
670 if (!ASCII_CHAR_P (c
))
672 c
= BYTE8_TO_CHAR (c
);
673 to_addr
+= CHAR_STRING (c
, to_addr
);
677 /* Special case for speed. */
678 *to_addr
++ = c
, nbytes
--;
680 return to_addr
- initial_to_addr
;
684 /* Return the number of bytes it would take
685 to convert some single-byte text to multibyte.
686 The single-byte text consists of NBYTES bytes at PTR. */
689 count_size_as_multibyte (const unsigned char *ptr
, EMACS_INT nbytes
)
692 EMACS_INT outgoing_nbytes
= 0;
694 for (i
= 0; i
< nbytes
; i
++)
696 unsigned int c
= *ptr
++;
698 if (ASCII_CHAR_P (c
))
702 c
= BYTE8_TO_CHAR (c
);
703 outgoing_nbytes
+= CHAR_BYTES (c
);
707 return outgoing_nbytes
;
710 /* Insert a string of specified length before point.
711 This function judges multibyteness based on
712 enable_multibyte_characters in the current buffer;
713 it never converts between single-byte and multibyte.
715 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
716 prepare_to_modify_buffer could relocate the text. */
719 insert (const unsigned char *string
, EMACS_INT nbytes
)
723 EMACS_INT len
= chars_in_text (string
, nbytes
), opoint
;
724 insert_1_both (string
, len
, nbytes
, 0, 1, 0);
726 signal_after_change (opoint
, 0, len
);
727 update_compositions (opoint
, PT
, CHECK_BORDER
);
731 /* Likewise, but inherit text properties from neighboring characters. */
734 insert_and_inherit (const unsigned char *string
, EMACS_INT nbytes
)
738 EMACS_INT len
= chars_in_text (string
, nbytes
), opoint
;
739 insert_1_both (string
, len
, nbytes
, 1, 1, 0);
741 signal_after_change (opoint
, 0, len
);
742 update_compositions (opoint
, PT
, CHECK_BORDER
);
746 /* Insert the character C before point. Do not inherit text properties. */
751 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
754 if (! NILP (current_buffer
->enable_multibyte_characters
))
755 len
= CHAR_STRING (c
, str
);
765 /* Insert the null-terminated string S before point. */
768 insert_string (const char *s
)
770 insert (s
, strlen (s
));
773 /* Like `insert' except that all markers pointing at the place where
774 the insertion happens are adjusted to point after it.
775 Don't use this function to insert part of a Lisp string,
776 since gc could happen and relocate it. */
779 insert_before_markers (const unsigned char *string
, EMACS_INT nbytes
)
783 EMACS_INT len
= chars_in_text (string
, nbytes
), opoint
;
784 insert_1_both (string
, len
, nbytes
, 0, 1, 1);
786 signal_after_change (opoint
, 0, len
);
787 update_compositions (opoint
, PT
, CHECK_BORDER
);
791 /* Likewise, but inherit text properties from neighboring characters. */
794 insert_before_markers_and_inherit (const unsigned char *string
,
799 EMACS_INT len
= chars_in_text (string
, nbytes
), opoint
;
800 insert_1_both (string
, len
, nbytes
, 1, 1, 1);
802 signal_after_change (opoint
, 0, len
);
803 update_compositions (opoint
, PT
, CHECK_BORDER
);
807 /* Subroutine used by the insert functions above. */
810 insert_1 (const unsigned char *string
, EMACS_INT nbytes
,
811 int inherit
, int prepare
, int before_markers
)
813 insert_1_both (string
, chars_in_text (string
, nbytes
), nbytes
,
814 inherit
, prepare
, before_markers
);
818 #ifdef BYTE_COMBINING_DEBUG
820 /* See if the bytes before POS/POS_BYTE combine with bytes
821 at the start of STRING to form a single character.
822 If so, return the number of bytes at the start of STRING
823 which combine in this way. Otherwise, return 0. */
826 count_combining_before (const unsigned char *string
, EMACS_INT length
,
827 EMACS_INT pos
, EMACS_INT pos_byte
)
829 int len
, combining_bytes
;
830 const unsigned char *p
;
832 if (NILP (current_buffer
->enable_multibyte_characters
))
835 /* At first, we can exclude the following cases:
836 (1) STRING[0] can't be a following byte of multibyte sequence.
837 (2) POS is the start of the current buffer.
838 (3) A character before POS is not a multibyte character. */
839 if (length
== 0 || CHAR_HEAD_P (*string
)) /* case (1) */
841 if (pos_byte
== BEG_BYTE
) /* case (2) */
844 p
= BYTE_POS_ADDR (pos_byte
- 1);
845 while (! CHAR_HEAD_P (*p
)) p
--, len
++;
846 if (! BASE_LEADING_CODE_P (*p
)) /* case (3) */
849 combining_bytes
= BYTES_BY_CHAR_HEAD (*p
) - len
;
850 if (combining_bytes
<= 0)
851 /* The character preceding POS is, complete and no room for
852 combining bytes (combining_bytes == 0), or an independent 8-bit
853 character (combining_bytes < 0). */
856 /* We have a combination situation. Count the bytes at STRING that
859 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
862 return (combining_bytes
< p
- string
? combining_bytes
: p
- string
);
865 /* See if the bytes after POS/POS_BYTE combine with bytes
866 at the end of STRING to form a single character.
867 If so, return the number of bytes after POS/POS_BYTE
868 which combine in this way. Otherwise, return 0. */
871 count_combining_after (const unsigned char *string
,
872 EMACS_INT length
, EMACS_INT pos
, EMACS_INT pos_byte
)
874 EMACS_INT opos_byte
= pos_byte
;
879 if (NILP (current_buffer
->enable_multibyte_characters
))
882 /* At first, we can exclude the following cases:
883 (1) The last byte of STRING is an ASCII.
884 (2) POS is the last of the current buffer.
885 (3) A character at POS can't be a following byte of multibyte
887 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1])) /* case (1) */
889 if (pos_byte
== Z_BYTE
) /* case (2) */
891 bufp
= BYTE_POS_ADDR (pos_byte
);
892 if (CHAR_HEAD_P (*bufp
)) /* case (3) */
896 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
902 /* All characters in STRING are not character head. We must
903 check also preceding bytes at POS. We are sure that the gap
905 unsigned char *p
= BEG_ADDR
;
907 while (i
>= 0 && ! CHAR_HEAD_P (p
[i
]))
909 if (i
< 0 || !BASE_LEADING_CODE_P (p
[i
]))
912 bytes
= BYTES_BY_CHAR_HEAD (p
[i
]);
913 return (bytes
<= pos_byte
- 1 - i
+ length
915 : bytes
- (pos_byte
- 1 - i
+ length
));
917 if (!BASE_LEADING_CODE_P (string
[i
]))
920 bytes
= BYTES_BY_CHAR_HEAD (string
[i
]) - (length
- i
);
922 while (!CHAR_HEAD_P (*bufp
)) bufp
++, pos_byte
++;
924 return (bytes
<= pos_byte
- opos_byte
? bytes
: pos_byte
- opos_byte
);
930 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
931 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
932 are the same as in insert_1. */
935 insert_1_both (const unsigned char *string
,
936 EMACS_INT nchars
, EMACS_INT nbytes
,
937 int inherit
, int prepare
, int before_markers
)
942 if (NILP (current_buffer
->enable_multibyte_characters
))
946 /* Do this before moving and increasing the gap,
947 because the before-change hooks might move the gap
948 or make it smaller. */
949 prepare_to_modify_buffer (PT
, PT
, NULL
);
952 move_gap_both (PT
, PT_BYTE
);
953 if (GAP_SIZE
< nbytes
)
954 make_gap (nbytes
- GAP_SIZE
);
956 #ifdef BYTE_COMBINING_DEBUG
957 if (count_combining_before (string
, nbytes
, PT
, PT_BYTE
)
958 || count_combining_after (string
, nbytes
, PT
, PT_BYTE
))
962 /* Record deletion of the surrounding text that combines with
963 the insertion. This, together with recording the insertion,
964 will add up to the right stuff in the undo list. */
965 record_insert (PT
, nchars
);
967 CHARS_MODIFF
= MODIFF
;
969 bcopy (string
, GPT_ADDR
, nbytes
);
978 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
983 /* The insert may have been in the unchanged region, so check again. */
984 if (Z
- GPT
< END_UNCHANGED
)
985 END_UNCHANGED
= Z
- GPT
;
987 adjust_overlays_for_insert (PT
, nchars
);
988 adjust_markers_for_insert (PT
, PT_BYTE
,
989 PT
+ nchars
, PT_BYTE
+ nbytes
,
992 if (BUF_INTERVALS (current_buffer
) != 0)
993 offset_intervals (current_buffer
, PT
, nchars
);
995 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
996 set_text_properties (make_number (PT
), make_number (PT
+ nchars
),
999 adjust_point (nchars
, nbytes
);
1004 /* Insert the part of the text of STRING, a Lisp object assumed to be
1005 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1006 starting at position POS / POS_BYTE. If the text of STRING has properties,
1007 copy them into the buffer.
1009 It does not work to use `insert' for this, because a GC could happen
1010 before we bcopy the stuff into the buffer, and relocate the string
1011 without insert noticing. */
1014 insert_from_string (Lisp_Object string
, EMACS_INT pos
, EMACS_INT pos_byte
,
1015 EMACS_INT length
, EMACS_INT length_byte
, int inherit
)
1017 EMACS_INT opoint
= PT
;
1019 if (SCHARS (string
) == 0)
1022 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1024 signal_after_change (opoint
, 0, PT
- opoint
);
1025 update_compositions (opoint
, PT
, CHECK_BORDER
);
1028 /* Like `insert_from_string' except that all markers pointing
1029 at the place where the insertion happens are adjusted to point after it. */
1032 insert_from_string_before_markers (Lisp_Object string
,
1033 EMACS_INT pos
, EMACS_INT pos_byte
,
1034 EMACS_INT length
, EMACS_INT length_byte
,
1037 EMACS_INT opoint
= PT
;
1039 if (SCHARS (string
) == 0)
1042 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1044 signal_after_change (opoint
, 0, PT
- opoint
);
1045 update_compositions (opoint
, PT
, CHECK_BORDER
);
1048 /* Subroutine of the insertion functions above. */
1051 insert_from_string_1 (Lisp_Object string
, EMACS_INT pos
, EMACS_INT pos_byte
,
1052 EMACS_INT nchars
, EMACS_INT nbytes
,
1053 int inherit
, int before_markers
)
1055 struct gcpro gcpro1
;
1056 EMACS_INT outgoing_nbytes
= nbytes
;
1059 /* Make OUTGOING_NBYTES describe the text
1060 as it will be inserted in this buffer. */
1062 if (NILP (current_buffer
->enable_multibyte_characters
))
1063 outgoing_nbytes
= nchars
;
1064 else if (! STRING_MULTIBYTE (string
))
1066 = count_size_as_multibyte (SDATA (string
) + pos_byte
,
1070 /* Do this before moving and increasing the gap,
1071 because the before-change hooks might move the gap
1072 or make it smaller. */
1073 prepare_to_modify_buffer (PT
, PT
, NULL
);
1076 move_gap_both (PT
, PT_BYTE
);
1077 if (GAP_SIZE
< outgoing_nbytes
)
1078 make_gap (outgoing_nbytes
- GAP_SIZE
);
1081 /* Copy the string text into the buffer, perhaps converting
1082 between single-byte and multibyte. */
1083 copy_text (SDATA (string
) + pos_byte
, GPT_ADDR
, nbytes
,
1084 STRING_MULTIBYTE (string
),
1085 ! NILP (current_buffer
->enable_multibyte_characters
));
1087 #ifdef BYTE_COMBINING_DEBUG
1088 /* We have copied text into the gap, but we have not altered
1089 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1090 to these functions and get the same results as we would
1091 have got earlier on. Meanwhile, PT_ADDR does point to
1092 the text that has been stored by copy_text. */
1093 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1094 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1098 record_insert (PT
, nchars
);
1100 CHARS_MODIFF
= MODIFF
;
1102 GAP_SIZE
-= outgoing_nbytes
;
1106 GPT_BYTE
+= outgoing_nbytes
;
1107 ZV_BYTE
+= outgoing_nbytes
;
1108 Z_BYTE
+= outgoing_nbytes
;
1109 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1114 /* The insert may have been in the unchanged region, so check again. */
1115 if (Z
- GPT
< END_UNCHANGED
)
1116 END_UNCHANGED
= Z
- GPT
;
1118 adjust_overlays_for_insert (PT
, nchars
);
1119 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1120 PT_BYTE
+ outgoing_nbytes
,
1123 offset_intervals (current_buffer
, PT
, nchars
);
1125 intervals
= STRING_INTERVALS (string
);
1126 /* Get the intervals for the part of the string we are inserting. */
1127 if (nbytes
< SBYTES (string
))
1128 intervals
= copy_intervals (intervals
, pos
, nchars
);
1130 /* Insert those intervals. */
1131 graft_intervals_into_buffer (intervals
, PT
, nchars
,
1132 current_buffer
, inherit
);
1134 adjust_point (nchars
, outgoing_nbytes
);
1139 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1140 starting at GPT_ADDR. */
1143 insert_from_gap (EMACS_INT nchars
, EMACS_INT nbytes
)
1145 if (NILP (current_buffer
->enable_multibyte_characters
))
1148 record_insert (GPT
, nchars
);
1158 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1163 adjust_overlays_for_insert (GPT
- nchars
, nchars
);
1164 adjust_markers_for_insert (GPT
- nchars
, GPT_BYTE
- nbytes
,
1167 if (BUF_INTERVALS (current_buffer
) != 0)
1169 offset_intervals (current_buffer
, GPT
- nchars
, nchars
);
1170 graft_intervals_into_buffer (NULL_INTERVAL
, GPT
- nchars
, nchars
,
1174 if (GPT
- nchars
< PT
)
1175 adjust_point (nchars
, nbytes
);
1180 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1181 current buffer. If the text in BUF has properties, they are absorbed
1182 into the current buffer.
1184 It does not work to use `insert' for this, because a malloc could happen
1185 and relocate BUF's text before the bcopy happens. */
1188 insert_from_buffer (struct buffer
*buf
,
1189 EMACS_INT charpos
, EMACS_INT nchars
, int inherit
)
1191 EMACS_INT opoint
= PT
;
1193 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1194 signal_after_change (opoint
, 0, PT
- opoint
);
1195 update_compositions (opoint
, PT
, CHECK_BORDER
);
1199 insert_from_buffer_1 (struct buffer
*buf
,
1200 EMACS_INT from
, EMACS_INT nchars
, int inherit
)
1202 register Lisp_Object temp
;
1203 EMACS_INT chunk
, chunk_expanded
;
1204 EMACS_INT from_byte
= buf_charpos_to_bytepos (buf
, from
);
1205 EMACS_INT to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1206 EMACS_INT incoming_nbytes
= to_byte
- from_byte
;
1207 EMACS_INT outgoing_nbytes
= incoming_nbytes
;
1210 /* Make OUTGOING_NBYTES describe the text
1211 as it will be inserted in this buffer. */
1213 if (NILP (current_buffer
->enable_multibyte_characters
))
1214 outgoing_nbytes
= nchars
;
1215 else if (NILP (buf
->enable_multibyte_characters
))
1217 EMACS_INT outgoing_before_gap
= 0;
1218 EMACS_INT outgoing_after_gap
= 0;
1220 if (from
< BUF_GPT (buf
))
1222 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1223 if (chunk
> incoming_nbytes
)
1224 chunk
= incoming_nbytes
;
1226 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1232 if (chunk
< incoming_nbytes
)
1234 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
,
1236 incoming_nbytes
- chunk
);
1238 outgoing_nbytes
= outgoing_before_gap
+ outgoing_after_gap
;
1241 /* Make sure point-max won't overflow after this insertion. */
1242 XSETINT (temp
, outgoing_nbytes
+ Z
);
1243 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1244 error ("Maximum buffer size exceeded");
1246 /* Do this before moving and increasing the gap,
1247 because the before-change hooks might move the gap
1248 or make it smaller. */
1249 prepare_to_modify_buffer (PT
, PT
, NULL
);
1252 move_gap_both (PT
, PT_BYTE
);
1253 if (GAP_SIZE
< outgoing_nbytes
)
1254 make_gap (outgoing_nbytes
- GAP_SIZE
);
1256 if (from
< BUF_GPT (buf
))
1258 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1259 if (chunk
> incoming_nbytes
)
1260 chunk
= incoming_nbytes
;
1261 /* Record number of output bytes, so we know where
1262 to put the output from the second copy_text. */
1264 = copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1266 ! NILP (buf
->enable_multibyte_characters
),
1267 ! NILP (current_buffer
->enable_multibyte_characters
));
1270 chunk_expanded
= chunk
= 0;
1272 if (chunk
< incoming_nbytes
)
1273 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1274 GPT_ADDR
+ chunk_expanded
, incoming_nbytes
- chunk
,
1275 ! NILP (buf
->enable_multibyte_characters
),
1276 ! NILP (current_buffer
->enable_multibyte_characters
));
1278 #ifdef BYTE_COMBINING_DEBUG
1279 /* We have copied text into the gap, but we have not altered
1280 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1281 to these functions and get the same results as we would
1282 have got earlier on. Meanwhile, GPT_ADDR does point to
1283 the text that has been stored by copy_text. */
1284 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1285 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1289 record_insert (PT
, nchars
);
1291 CHARS_MODIFF
= MODIFF
;
1293 GAP_SIZE
-= outgoing_nbytes
;
1297 GPT_BYTE
+= outgoing_nbytes
;
1298 ZV_BYTE
+= outgoing_nbytes
;
1299 Z_BYTE
+= outgoing_nbytes
;
1300 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1305 /* The insert may have been in the unchanged region, so check again. */
1306 if (Z
- GPT
< END_UNCHANGED
)
1307 END_UNCHANGED
= Z
- GPT
;
1309 adjust_overlays_for_insert (PT
, nchars
);
1310 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1311 PT_BYTE
+ outgoing_nbytes
,
1314 if (BUF_INTERVALS (current_buffer
) != 0)
1315 offset_intervals (current_buffer
, PT
, nchars
);
1317 /* Get the intervals for the part of the string we are inserting. */
1318 intervals
= BUF_INTERVALS (buf
);
1319 if (nchars
< BUF_Z (buf
) - BUF_BEG (buf
))
1321 if (buf
== current_buffer
&& PT
<= from
)
1323 intervals
= copy_intervals (intervals
, from
, nchars
);
1326 /* Insert those intervals. */
1327 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1329 adjust_point (nchars
, outgoing_nbytes
);
1332 /* Record undo information and adjust markers and position keepers for
1333 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1334 chars (LEN_BYTE bytes) which resides in the gap just after
1337 PREV_TEXT nil means the new text was just inserted. */
1340 adjust_after_replace (EMACS_INT from
, EMACS_INT from_byte
,
1341 Lisp_Object prev_text
, EMACS_INT len
, EMACS_INT len_byte
)
1343 EMACS_INT nchars_del
= 0, nbytes_del
= 0;
1345 #ifdef BYTE_COMBINING_DEBUG
1346 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1347 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1351 if (STRINGP (prev_text
))
1353 nchars_del
= SCHARS (prev_text
);
1354 nbytes_del
= SBYTES (prev_text
);
1357 /* Update various buffer positions for the new text. */
1358 GAP_SIZE
-= len_byte
;
1360 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1361 GPT
+= len
; GPT_BYTE
+= len_byte
;
1362 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1365 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1368 adjust_markers_for_insert (from
, from_byte
,
1369 from
+ len
, from_byte
+ len_byte
, 0);
1371 if (! EQ (current_buffer
->undo_list
, Qt
))
1374 record_delete (from
, prev_text
);
1375 record_insert (from
, len
);
1378 if (len
> nchars_del
)
1379 adjust_overlays_for_insert (from
, len
- nchars_del
);
1380 else if (len
< nchars_del
)
1381 adjust_overlays_for_delete (from
, nchars_del
- len
);
1382 if (BUF_INTERVALS (current_buffer
) != 0)
1384 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1388 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1390 /* As byte combining will decrease Z, we must check this again. */
1391 if (Z
- GPT
< END_UNCHANGED
)
1392 END_UNCHANGED
= Z
- GPT
;
1397 evaporate_overlays (from
);
1399 CHARS_MODIFF
= MODIFF
;
1402 /* Like adjust_after_replace, but doesn't require PREV_TEXT.
1403 This is for use when undo is not enabled in the current buffer. */
1406 adjust_after_replace_noundo (EMACS_INT from
, EMACS_INT from_byte
,
1407 EMACS_INT nchars_del
, EMACS_INT nbytes_del
,
1408 EMACS_INT len
, EMACS_INT len_byte
)
1410 #ifdef BYTE_COMBINING_DEBUG
1411 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1412 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1416 /* Update various buffer positions for the new text. */
1417 GAP_SIZE
-= len_byte
;
1419 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1420 GPT
+= len
; GPT_BYTE
+= len_byte
;
1421 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1424 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1427 adjust_markers_for_insert (from
, from_byte
,
1428 from
+ len
, from_byte
+ len_byte
, 0);
1430 if (len
> nchars_del
)
1431 adjust_overlays_for_insert (from
, len
- nchars_del
);
1432 else if (len
< nchars_del
)
1433 adjust_overlays_for_delete (from
, nchars_del
- len
);
1434 if (BUF_INTERVALS (current_buffer
) != 0)
1436 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1440 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1442 /* As byte combining will decrease Z, we must check this again. */
1443 if (Z
- GPT
< END_UNCHANGED
)
1444 END_UNCHANGED
= Z
- GPT
;
1449 evaporate_overlays (from
);
1451 CHARS_MODIFF
= MODIFF
;
1454 /* Record undo information, adjust markers and position keepers for an
1455 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1456 text already exists in the current buffer but character length (TO
1457 - FROM) may be incorrect, the correct length is NEWLEN. */
1460 adjust_after_insert (EMACS_INT from
, EMACS_INT from_byte
,
1461 EMACS_INT to
, EMACS_INT to_byte
, EMACS_INT newlen
)
1463 EMACS_INT len
= to
- from
, len_byte
= to_byte
- from_byte
;
1466 move_gap_both (to
, to_byte
);
1467 GAP_SIZE
+= len_byte
;
1468 GPT
-= len
; GPT_BYTE
-= len_byte
;
1469 ZV
-= len
; ZV_BYTE
-= len_byte
;
1470 Z
-= len
; Z_BYTE
-= len_byte
;
1471 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1474 /* Replace the text from character positions FROM to TO with NEW,
1475 If PREPARE is nonzero, call prepare_to_modify_buffer.
1476 If INHERIT, the newly inserted text should inherit text properties
1477 from the surrounding non-deleted text. */
1479 /* Note that this does not yet handle markers quite right.
1480 Also it needs to record a single undo-entry that does a replacement
1481 rather than a separate delete and insert.
1482 That way, undo will also handle markers properly.
1484 But if MARKERS is 0, don't relocate markers. */
1487 replace_range (EMACS_INT from
, EMACS_INT to
, Lisp_Object
new,
1488 int prepare
, int inherit
, int markers
)
1490 EMACS_INT inschars
= SCHARS (new);
1491 EMACS_INT insbytes
= SBYTES (new);
1492 EMACS_INT from_byte
, to_byte
;
1493 EMACS_INT nbytes_del
, nchars_del
;
1494 register Lisp_Object temp
;
1495 struct gcpro gcpro1
;
1497 EMACS_INT outgoing_insbytes
= insbytes
;
1498 Lisp_Object deletion
;
1507 EMACS_INT range_length
= to
- from
;
1508 prepare_to_modify_buffer (from
, to
, &from
);
1509 to
= from
+ range_length
;
1514 /* Make args be valid */
1520 from_byte
= CHAR_TO_BYTE (from
);
1521 to_byte
= CHAR_TO_BYTE (to
);
1523 nchars_del
= to
- from
;
1524 nbytes_del
= to_byte
- from_byte
;
1526 if (nbytes_del
<= 0 && insbytes
== 0)
1529 /* Make OUTGOING_INSBYTES describe the text
1530 as it will be inserted in this buffer. */
1532 if (NILP (current_buffer
->enable_multibyte_characters
))
1533 outgoing_insbytes
= inschars
;
1534 else if (! STRING_MULTIBYTE (new))
1536 = count_size_as_multibyte (SDATA (new), insbytes
);
1538 /* Make sure point-max won't overflow after this insertion. */
1539 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1540 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1541 error ("Maximum buffer size exceeded");
1545 /* Make sure the gap is somewhere in or next to what we are deleting. */
1547 gap_right (from
, from_byte
);
1549 gap_left (to
, to_byte
, 0);
1551 /* Even if we don't record for undo, we must keep the original text
1552 because we may have to recover it because of inappropriate byte
1554 if (! EQ (current_buffer
->undo_list
, Qt
))
1555 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1557 GAP_SIZE
+= nbytes_del
;
1560 ZV_BYTE
-= nbytes_del
;
1561 Z_BYTE
-= nbytes_del
;
1563 GPT_BYTE
= from_byte
;
1564 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1569 if (GPT
- BEG
< BEG_UNCHANGED
)
1570 BEG_UNCHANGED
= GPT
- BEG
;
1571 if (Z
- GPT
< END_UNCHANGED
)
1572 END_UNCHANGED
= Z
- GPT
;
1574 if (GAP_SIZE
< insbytes
)
1575 make_gap (insbytes
- GAP_SIZE
);
1577 /* Copy the string text into the buffer, perhaps converting
1578 between single-byte and multibyte. */
1579 copy_text (SDATA (new), GPT_ADDR
, insbytes
,
1580 STRING_MULTIBYTE (new),
1581 ! NILP (current_buffer
->enable_multibyte_characters
));
1583 #ifdef BYTE_COMBINING_DEBUG
1584 /* We have copied text into the gap, but we have not marked
1585 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1586 here, for both the previous text and the following text.
1587 Meanwhile, GPT_ADDR does point to
1588 the text that has been stored by copy_text. */
1589 if (count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
)
1590 || count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
))
1594 if (! EQ (current_buffer
->undo_list
, Qt
))
1596 /* Record the insertion first, so that when we undo,
1597 the deletion will be undone first. Thus, undo
1598 will insert before deleting, and thus will keep
1599 the markers before and after this text separate. */
1600 record_insert (from
+ SCHARS (deletion
), inschars
);
1601 record_delete (from
, deletion
);
1604 GAP_SIZE
-= outgoing_insbytes
;
1608 GPT_BYTE
+= outgoing_insbytes
;
1609 ZV_BYTE
+= outgoing_insbytes
;
1610 Z_BYTE
+= outgoing_insbytes
;
1611 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1616 /* Adjust the overlay center as needed. This must be done after
1617 adjusting the markers that bound the overlays. */
1618 adjust_overlays_for_delete (from
, nchars_del
);
1619 adjust_overlays_for_insert (from
, inschars
);
1621 /* Adjust markers for the deletion and the insertion. */
1623 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1624 inschars
, outgoing_insbytes
);
1626 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1628 /* Get the intervals for the part of the string we are inserting--
1629 not including the combined-before bytes. */
1630 intervals
= STRING_INTERVALS (new);
1631 /* Insert those intervals. */
1632 graft_intervals_into_buffer (intervals
, from
, inschars
,
1633 current_buffer
, inherit
);
1635 /* Relocate point as if it were a marker. */
1637 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1638 (from_byte
+ outgoing_insbytes
1639 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1641 if (outgoing_insbytes
== 0)
1642 evaporate_overlays (from
);
1647 CHARS_MODIFF
= MODIFF
;
1650 signal_after_change (from
, nchars_del
, GPT
- from
);
1651 update_compositions (from
, GPT
, CHECK_BORDER
);
1654 /* Replace the text from character positions FROM to TO with
1655 the text in INS of length INSCHARS.
1656 Keep the text properties that applied to the old characters
1657 (extending them to all the new chars if there are more new chars).
1659 Note that this does not yet handle markers quite right.
1661 If MARKERS is nonzero, relocate markers.
1663 Unlike most functions at this level, never call
1664 prepare_to_modify_buffer and never call signal_after_change. */
1667 replace_range_2 (EMACS_INT from
, EMACS_INT from_byte
,
1668 EMACS_INT to
, EMACS_INT to_byte
,
1669 char *ins
, EMACS_INT inschars
, EMACS_INT insbytes
,
1672 EMACS_INT nbytes_del
, nchars_del
;
1677 nchars_del
= to
- from
;
1678 nbytes_del
= to_byte
- from_byte
;
1680 if (nbytes_del
<= 0 && insbytes
== 0)
1683 /* Make sure point-max won't overflow after this insertion. */
1684 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1685 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1686 error ("Maximum buffer size exceeded");
1688 /* Make sure the gap is somewhere in or next to what we are deleting. */
1690 gap_right (from
, from_byte
);
1692 gap_left (to
, to_byte
, 0);
1694 GAP_SIZE
+= nbytes_del
;
1697 ZV_BYTE
-= nbytes_del
;
1698 Z_BYTE
-= nbytes_del
;
1700 GPT_BYTE
= from_byte
;
1701 if (GAP_SIZE
> 0) *(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 replacement text into the buffer. */
1715 bcopy (ins
, GPT_ADDR
, insbytes
);
1717 #ifdef BYTE_COMBINING_DEBUG
1718 /* We have copied text into the gap, but we have not marked
1719 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1720 here, for both the previous text and the following text.
1721 Meanwhile, GPT_ADDR does point to
1722 the text that has been stored by copy_text. */
1723 if (count_combining_before (GPT_ADDR
, insbytes
, from
, from_byte
)
1724 || count_combining_after (GPT_ADDR
, insbytes
, from
, from_byte
))
1728 GAP_SIZE
-= insbytes
;
1732 GPT_BYTE
+= insbytes
;
1733 ZV_BYTE
+= insbytes
;
1735 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1740 /* Adjust the overlay center as needed. This must be done after
1741 adjusting the markers that bound the overlays. */
1742 if (nchars_del
!= inschars
)
1744 adjust_overlays_for_insert (from
, inschars
);
1745 adjust_overlays_for_delete (from
+ inschars
, nchars_del
);
1748 /* Adjust markers for the deletion and the insertion. */
1750 && ! (nchars_del
== 1 && inschars
== 1 && nbytes_del
== insbytes
))
1751 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1752 inschars
, insbytes
);
1754 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1756 /* Relocate point as if it were a marker. */
1757 if (from
< PT
&& (nchars_del
!= inschars
|| nbytes_del
!= insbytes
))
1760 /* PT was within the deleted text. Move it to FROM. */
1761 adjust_point (from
- PT
, from_byte
- PT_BYTE
);
1763 adjust_point (inschars
- nchars_del
, insbytes
- nbytes_del
);
1767 evaporate_overlays (from
);
1772 CHARS_MODIFF
= MODIFF
;
1775 /* Delete characters in current buffer
1776 from FROM up to (but not including) TO.
1777 If TO comes before FROM, we delete nothing. */
1780 del_range (EMACS_INT from
, EMACS_INT to
)
1782 del_range_1 (from
, to
, 1, 0);
1785 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1786 RET_STRING says to return the deleted text. */
1789 del_range_1 (EMACS_INT from
, EMACS_INT to
, int prepare
, int ret_string
)
1791 EMACS_INT from_byte
, to_byte
;
1792 Lisp_Object deletion
;
1793 struct gcpro gcpro1
;
1795 /* Make args be valid */
1806 EMACS_INT range_length
= to
- from
;
1807 prepare_to_modify_buffer (from
, to
, &from
);
1808 to
= min (ZV
, from
+ range_length
);
1811 from_byte
= CHAR_TO_BYTE (from
);
1812 to_byte
= CHAR_TO_BYTE (to
);
1814 deletion
= del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
);
1816 signal_after_change (from
, to
- from
, 0);
1817 update_compositions (from
, from
, CHECK_HEAD
);
1822 /* Like del_range_1 but args are byte positions, not char positions. */
1825 del_range_byte (EMACS_INT from_byte
, EMACS_INT to_byte
, int prepare
)
1829 /* Make args be valid */
1830 if (from_byte
< BEGV_BYTE
)
1831 from_byte
= BEGV_BYTE
;
1832 if (to_byte
> ZV_BYTE
)
1835 if (to_byte
<= from_byte
)
1838 from
= BYTE_TO_CHAR (from_byte
);
1839 to
= BYTE_TO_CHAR (to_byte
);
1843 EMACS_INT old_from
= from
, old_to
= Z
- to
;
1844 EMACS_INT range_length
= to
- from
;
1845 prepare_to_modify_buffer (from
, to
, &from
);
1846 to
= from
+ range_length
;
1848 if (old_from
!= from
)
1849 from_byte
= CHAR_TO_BYTE (from
);
1855 else if (old_to
== Z
- to
)
1856 to_byte
= CHAR_TO_BYTE (to
);
1859 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1860 signal_after_change (from
, to
- from
, 0);
1861 update_compositions (from
, from
, CHECK_HEAD
);
1864 /* Like del_range_1, but positions are specified both as charpos
1868 del_range_both (EMACS_INT from
, EMACS_INT from_byte
,
1869 EMACS_INT to
, EMACS_INT to_byte
, int prepare
)
1871 /* Make args be valid */
1872 if (from_byte
< BEGV_BYTE
)
1873 from_byte
= BEGV_BYTE
;
1874 if (to_byte
> ZV_BYTE
)
1877 if (to_byte
<= from_byte
)
1887 EMACS_INT old_from
= from
, old_to
= Z
- to
;
1888 EMACS_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
);
1899 else if (old_to
== Z
- to
)
1900 to_byte
= CHAR_TO_BYTE (to
);
1903 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1904 signal_after_change (from
, to
- from
, 0);
1905 update_compositions (from
, from
, CHECK_HEAD
);
1908 /* Delete a range of text, specified both as character positions
1909 and byte positions. FROM and TO are character positions,
1910 while FROM_BYTE and TO_BYTE are byte positions.
1911 If RET_STRING is true, the deleted area is returned as a string. */
1914 del_range_2 (EMACS_INT from
, EMACS_INT from_byte
,
1915 EMACS_INT to
, EMACS_INT to_byte
, int ret_string
)
1917 register EMACS_INT nbytes_del
, nchars_del
;
1918 Lisp_Object deletion
;
1922 nchars_del
= to
- from
;
1923 nbytes_del
= to_byte
- from_byte
;
1925 /* Make sure the gap is somewhere in or next to what we are deleting. */
1927 gap_right (from
, from_byte
);
1929 gap_left (to
, to_byte
, 0);
1931 #ifdef BYTE_COMBINING_DEBUG
1932 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
1933 Z_BYTE
- to_byte
, from
, from_byte
))
1937 if (ret_string
|| ! EQ (current_buffer
->undo_list
, Qt
))
1938 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1942 /* Relocate all markers pointing into the new, larger gap
1943 to point at the end of the text before the gap.
1944 Do this before recording the deletion,
1945 so that undo handles this after reinserting the text. */
1946 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1948 if (! EQ (current_buffer
->undo_list
, Qt
))
1949 record_delete (from
, deletion
);
1951 CHARS_MODIFF
= MODIFF
;
1953 /* Relocate point as if it were a marker. */
1955 adjust_point (from
- (PT
< to
? PT
: to
),
1956 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
1958 offset_intervals (current_buffer
, from
, - nchars_del
);
1960 /* Adjust the overlay center as needed. This must be done after
1961 adjusting the markers that bound the overlays. */
1962 adjust_overlays_for_delete (from
, nchars_del
);
1964 GAP_SIZE
+= nbytes_del
;
1965 ZV_BYTE
-= nbytes_del
;
1966 Z_BYTE
-= nbytes_del
;
1970 GPT_BYTE
= from_byte
;
1971 if (GAP_SIZE
> 0 && !current_buffer
->text
->inhibit_shrinking
)
1972 /* Put an anchor, unless called from decode_coding_object which
1973 needs to access the previous gap contents. */
1979 if (GPT
- BEG
< BEG_UNCHANGED
)
1980 BEG_UNCHANGED
= GPT
- BEG
;
1981 if (Z
- GPT
< END_UNCHANGED
)
1982 END_UNCHANGED
= Z
- GPT
;
1986 evaporate_overlays (from
);
1991 /* Call this if you're about to change the region of BUFFER from
1992 character positions START to END. This checks the read-only
1993 properties of the region, calls the necessary modification hooks,
1994 and warns the next redisplay that it should pay attention to that
1997 If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
1998 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
2001 modify_region (struct buffer
*buffer
, EMACS_INT start
, EMACS_INT end
,
2002 int preserve_chars_modiff
)
2004 struct buffer
*old_buffer
= current_buffer
;
2006 if (buffer
!= old_buffer
)
2007 set_buffer_internal (buffer
);
2009 prepare_to_modify_buffer (start
, end
, NULL
);
2011 BUF_COMPUTE_UNCHANGED (buffer
, start
- 1, end
);
2013 if (MODIFF
<= SAVE_MODIFF
)
2014 record_first_change ();
2016 if (! preserve_chars_modiff
)
2017 CHARS_MODIFF
= MODIFF
;
2019 buffer
->point_before_scroll
= Qnil
;
2021 if (buffer
!= old_buffer
)
2022 set_buffer_internal (old_buffer
);
2025 /* Check that it is okay to modify the buffer between START and END,
2026 which are char positions.
2028 Run the before-change-function, if any. If intervals are in use,
2029 verify that the text to be modified is not read-only, and call
2030 any modification properties the text may have.
2032 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2033 by holding its value temporarily in a marker. */
2036 prepare_to_modify_buffer (EMACS_INT start
, EMACS_INT end
,
2037 EMACS_INT
*preserve_ptr
)
2039 struct buffer
*base_buffer
;
2041 if (!NILP (current_buffer
->read_only
))
2042 Fbarf_if_buffer_read_only ();
2044 /* Let redisplay consider other windows than selected_window
2045 if modifying another buffer. */
2046 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
2047 ++windows_or_buffers_changed
;
2049 if (BUF_INTERVALS (current_buffer
) != 0)
2053 Lisp_Object preserve_marker
;
2054 struct gcpro gcpro1
;
2055 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
2056 GCPRO1 (preserve_marker
);
2057 verify_interval_modification (current_buffer
, start
, end
);
2058 *preserve_ptr
= marker_position (preserve_marker
);
2059 unchain_marker (XMARKER (preserve_marker
));
2063 verify_interval_modification (current_buffer
, start
, end
);
2066 /* For indirect buffers, use the base buffer to check clashes. */
2067 if (current_buffer
->base_buffer
!= 0)
2068 base_buffer
= current_buffer
->base_buffer
;
2070 base_buffer
= current_buffer
;
2072 #ifdef CLASH_DETECTION
2073 if (!NILP (base_buffer
->file_truename
)
2074 /* Make binding buffer-file-name to nil effective. */
2075 && !NILP (base_buffer
->filename
)
2076 && SAVE_MODIFF
>= MODIFF
)
2077 lock_file (base_buffer
->file_truename
);
2079 /* At least warn if this file has changed on disk since it was visited. */
2080 if (!NILP (base_buffer
->filename
)
2081 && SAVE_MODIFF
>= MODIFF
2082 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2083 && !NILP (Ffile_exists_p (base_buffer
->filename
)))
2084 call1 (intern ("ask-user-about-supersession-threat"),
2085 base_buffer
->filename
);
2086 #endif /* not CLASH_DETECTION */
2088 signal_before_change (start
, end
, preserve_ptr
);
2090 if (current_buffer
->newline_cache
)
2091 invalidate_region_cache (current_buffer
,
2092 current_buffer
->newline_cache
,
2093 start
- BEG
, Z
- end
);
2094 if (current_buffer
->width_run_cache
)
2095 invalidate_region_cache (current_buffer
,
2096 current_buffer
->width_run_cache
,
2097 start
- BEG
, Z
- end
);
2099 Vdeactivate_mark
= Qt
;
2102 /* These macros work with an argument named `preserve_ptr'
2103 and a local variable named `preserve_marker'. */
2105 #define PRESERVE_VALUE \
2106 if (preserve_ptr && NILP (preserve_marker)) \
2107 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2109 #define RESTORE_VALUE \
2110 if (! NILP (preserve_marker)) \
2112 *preserve_ptr = marker_position (preserve_marker); \
2113 unchain_marker (XMARKER (preserve_marker)); \
2116 #define PRESERVE_START_END \
2117 if (NILP (start_marker)) \
2118 start_marker = Fcopy_marker (start, Qnil); \
2119 if (NILP (end_marker)) \
2120 end_marker = Fcopy_marker (end, Qnil);
2122 #define FETCH_START \
2123 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2126 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2128 /* Set a variable to nil if an error occurred.
2129 Don't change the variable if there was no error.
2130 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
2131 VARIABLE is the variable to maybe set to nil.
2132 NO-ERROR-FLAG is nil if there was an error,
2133 anything else meaning no error (so this function does nothing). */
2135 reset_var_on_error (val
)
2138 if (NILP (XCDR (val
)))
2139 Fset (XCAR (val
), Qnil
);
2143 /* Signal a change to the buffer immediately before it happens.
2144 START_INT and END_INT are the bounds of the text to be changed.
2146 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2147 by holding its value temporarily in a marker. */
2150 signal_before_change (EMACS_INT start_int
, EMACS_INT end_int
,
2151 EMACS_INT
*preserve_ptr
)
2153 Lisp_Object start
, end
;
2154 Lisp_Object start_marker
, end_marker
;
2155 Lisp_Object preserve_marker
;
2156 struct gcpro gcpro1
, gcpro2
, gcpro3
;
2157 int count
= SPECPDL_INDEX ();
2159 if (inhibit_modification_hooks
)
2162 start
= make_number (start_int
);
2163 end
= make_number (end_int
);
2164 preserve_marker
= Qnil
;
2165 start_marker
= Qnil
;
2167 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
2169 specbind (Qinhibit_modification_hooks
, Qt
);
2171 /* If buffer is unmodified, run a special hook for that case. */
2172 if (SAVE_MODIFF
>= MODIFF
2173 && !NILP (Vfirst_change_hook
)
2174 && !NILP (Vrun_hooks
))
2178 call1 (Vrun_hooks
, Qfirst_change_hook
);
2181 /* Now run the before-change-functions if any. */
2182 if (!NILP (Vbefore_change_functions
))
2184 Lisp_Object args
[3];
2185 Lisp_Object rvoe_arg
= Fcons (Qbefore_change_functions
, Qnil
);
2190 /* Mark before-change-functions to be reset to nil in case of error. */
2191 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2193 /* Actually run the hook functions. */
2194 args
[0] = Qbefore_change_functions
;
2195 args
[1] = FETCH_START
;
2196 args
[2] = FETCH_END
;
2197 Frun_hook_with_args (3, args
);
2199 /* There was no error: unarm the reset_on_error. */
2200 XSETCDR (rvoe_arg
, Qt
);
2203 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2206 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2207 FETCH_START
, FETCH_END
, Qnil
);
2210 if (! NILP (start_marker
))
2211 free_marker (start_marker
);
2212 if (! NILP (end_marker
))
2213 free_marker (end_marker
);
2217 unbind_to (count
, Qnil
);
2220 /* Signal a change immediately after it happens.
2221 CHARPOS is the character position of the start of the changed text.
2222 LENDEL is the number of characters of the text before the change.
2223 (Not the whole buffer; just the part that was changed.)
2224 LENINS is the number of characters in that part of the text
2225 after the change. */
2228 signal_after_change (EMACS_INT charpos
, EMACS_INT lendel
, EMACS_INT lenins
)
2230 int count
= SPECPDL_INDEX ();
2231 if (inhibit_modification_hooks
)
2234 /* If we are deferring calls to the after-change functions
2235 and there are no before-change functions,
2236 just record the args that we were going to use. */
2237 if (! NILP (Vcombine_after_change_calls
)
2238 && NILP (Vbefore_change_functions
)
2239 && !current_buffer
->overlays_before
2240 && !current_buffer
->overlays_after
)
2244 if (!NILP (combine_after_change_list
)
2245 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2246 Fcombine_after_change_execute ();
2248 elt
= Fcons (make_number (charpos
- BEG
),
2249 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2250 Fcons (make_number (lenins
- lendel
), Qnil
)));
2251 combine_after_change_list
2252 = Fcons (elt
, combine_after_change_list
);
2253 combine_after_change_buffer
= Fcurrent_buffer ();
2258 if (!NILP (combine_after_change_list
))
2259 Fcombine_after_change_execute ();
2261 specbind (Qinhibit_modification_hooks
, Qt
);
2263 if (!NILP (Vafter_change_functions
))
2265 Lisp_Object args
[4];
2266 Lisp_Object rvoe_arg
= Fcons (Qafter_change_functions
, Qnil
);
2268 /* Mark after-change-functions to be reset to nil in case of error. */
2269 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2271 /* Actually run the hook functions. */
2272 args
[0] = Qafter_change_functions
;
2273 XSETFASTINT (args
[1], charpos
);
2274 XSETFASTINT (args
[2], charpos
+ lenins
);
2275 XSETFASTINT (args
[3], lendel
);
2276 Frun_hook_with_args (4, args
);
2278 /* There was no error: unarm the reset_on_error. */
2279 XSETCDR (rvoe_arg
, Qt
);
2282 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2283 report_overlay_modification (make_number (charpos
),
2284 make_number (charpos
+ lenins
),
2286 make_number (charpos
),
2287 make_number (charpos
+ lenins
),
2288 make_number (lendel
));
2290 /* After an insertion, call the text properties
2291 insert-behind-hooks or insert-in-front-hooks. */
2293 report_interval_modification (make_number (charpos
),
2294 make_number (charpos
+ lenins
));
2296 unbind_to (count
, Qnil
);
2300 Fcombine_after_change_execute_1 (val
)
2303 Vcombine_after_change_calls
= val
;
2307 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2308 Scombine_after_change_execute
, 0, 0, 0,
2309 doc
: /* This function is for use internally in `combine-after-change-calls'. */)
2312 int count
= SPECPDL_INDEX ();
2313 EMACS_INT beg
, end
, change
;
2314 EMACS_INT begpos
, endpos
;
2317 if (NILP (combine_after_change_list
))
2320 /* It is rare for combine_after_change_buffer to be invalid, but
2321 possible. It can happen when combine-after-change-calls is
2322 non-nil, and insertion calls a file handler (e.g. through
2323 lock_file) which scribbles into a temp file -- cyd */
2324 if (!BUFFERP (combine_after_change_buffer
)
2325 || NILP (XBUFFER (combine_after_change_buffer
)->name
))
2327 combine_after_change_list
= Qnil
;
2331 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2333 Fset_buffer (combine_after_change_buffer
);
2335 /* # chars unchanged at beginning of buffer. */
2337 /* # chars unchanged at end of buffer. */
2339 /* Total amount of insertion (negative for deletion). */
2342 /* Scan the various individual changes,
2343 accumulating the range info in BEG, END and CHANGE. */
2344 for (tail
= combine_after_change_list
; CONSP (tail
);
2348 EMACS_INT thisbeg
, thisend
, thischange
;
2350 /* Extract the info from the next element. */
2354 thisbeg
= XINT (XCAR (elt
));
2359 thisend
= XINT (XCAR (elt
));
2364 thischange
= XINT (XCAR (elt
));
2366 /* Merge this range into the accumulated range. */
2367 change
+= thischange
;
2374 /* Get the current start and end positions of the range
2375 that was changed. */
2379 /* We are about to handle these, so discard them. */
2380 combine_after_change_list
= Qnil
;
2382 /* Now run the after-change functions for real.
2383 Turn off the flag that defers them. */
2384 record_unwind_protect (Fcombine_after_change_execute_1
,
2385 Vcombine_after_change_calls
);
2386 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2387 update_compositions (begpos
, endpos
, CHECK_ALL
);
2389 return unbind_to (count
, Qnil
);
2395 staticpro (&combine_after_change_list
);
2396 staticpro (&combine_after_change_buffer
);
2397 combine_after_change_list
= Qnil
;
2398 combine_after_change_buffer
= Qnil
;
2400 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag
,
2401 doc
: /* Non-nil means enable debugging checks for invalid marker positions. */);
2402 check_markers_debug_flag
= 0;
2403 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls
,
2404 doc
: /* Used internally by the `combine-after-change-calls' macro. */);
2405 Vcombine_after_change_calls
= Qnil
;
2407 DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks
,
2408 doc
: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2409 This affects `before-change-functions' and `after-change-functions',
2410 as well as hooks attached to text properties and overlays. */);
2411 inhibit_modification_hooks
= 0;
2412 Qinhibit_modification_hooks
= intern_c_string ("inhibit-modification-hooks");
2413 staticpro (&Qinhibit_modification_hooks
);
2415 defsubr (&Scombine_after_change_execute
);
2418 /* arch-tag: 9b34b886-47d7-465e-a234-299af411b23d
2419 (do not change this comment) */