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 (void);
56 /* Non-nil means don't call the after-change-functions right away,
57 just record an element in combine_after_change_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 memmove (to
, from
, i
);
172 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
173 BYTEPOS is where the loop above stopped, which may be what was specified
174 or may be where a quit was detected. */
175 adjust_markers_gap_motion (bytepos
, GPT_BYTE
, GAP_SIZE
);
178 if (bytepos
< charpos
)
180 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
184 /* Move the gap to a position greater than the current GPT.
185 BYTEPOS describes the new position as a byte position,
186 and CHARPOS is the corresponding char position. */
189 gap_right (EMACS_INT charpos
, EMACS_INT bytepos
)
191 register unsigned char *to
, *from
;
192 register EMACS_INT i
;
195 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
202 /* Now copy the characters. To move the gap up,
203 copy characters down. */
207 /* I gets number of characters left to copy. */
208 i
= bytepos
- new_s1
;
211 /* If a quit is requested, stop copying now.
212 Change BYTEPOS to be where we have actually moved the gap to. */
216 charpos
= BYTE_TO_CHAR (bytepos
);
219 /* Move at most 32000 chars before checking again for a quit. */
223 memmove (to
, from
, i
);
227 adjust_markers_gap_motion (GPT_BYTE
+ GAP_SIZE
, bytepos
+ GAP_SIZE
,
231 if (bytepos
< charpos
)
233 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
237 /* Add AMOUNT to the byte position of every marker in the current buffer
238 whose current byte position is between FROM (exclusive) and TO (inclusive).
240 Also, any markers past the outside of that interval, in the direction
241 of adjustment, are first moved back to the near end of the interval
242 and then adjusted by AMOUNT.
244 When the latter adjustment is done, if AMOUNT is negative,
245 we record the adjustment for undo. (This case happens only for
248 The markers' character positions are not altered,
249 because gap motion does not affect character positions. */
251 int adjust_markers_test
;
254 adjust_markers_gap_motion (EMACS_INT from
, EMACS_INT to
, EMACS_INT amount
)
256 /* Now that a marker has a bytepos, not counting the gap,
257 nothing needs to be done here. */
260 register struct Lisp_Marker
*m
;
261 register EMACS_INT mpos
;
263 marker
= BUF_MARKERS (current_buffer
);
265 while (!NILP (marker
))
267 m
= XMARKER (marker
);
271 if (mpos
> to
&& mpos
< to
+ amount
)
273 if (adjust_markers_test
)
280 /* Here's the case where a marker is inside text being deleted.
281 AMOUNT can be negative for gap motion, too,
282 but then this range contains no markers. */
283 if (mpos
> from
+ amount
&& mpos
<= from
)
285 if (adjust_markers_test
)
287 mpos
= from
+ amount
;
290 if (mpos
> from
&& mpos
<= to
)
298 /* Adjust all markers for a deletion
299 whose range in bytes is FROM_BYTE to TO_BYTE.
300 The range in charpos is FROM to TO.
302 This function assumes that the gap is adjacent to
303 or inside of the range being deleted. */
306 adjust_markers_for_delete (EMACS_INT from
, EMACS_INT from_byte
,
307 EMACS_INT to
, EMACS_INT to_byte
)
310 register struct Lisp_Marker
*m
;
311 register EMACS_INT charpos
;
313 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
315 charpos
= m
->charpos
;
320 /* If the marker is after the deletion,
321 relocate by number of chars / bytes deleted. */
324 m
->charpos
-= to
- from
;
325 m
->bytepos
-= to_byte
- from_byte
;
327 /* Here's the case where a marker is inside text being deleted. */
328 else if (charpos
> from
)
330 if (! m
->insertion_type
)
331 { /* Normal markers will end up at the beginning of the
332 re-inserted text after undoing a deletion, and must be
333 adjusted to move them to the correct place. */
334 XSETMISC (marker
, m
);
335 record_marker_adjustment (marker
, from
- charpos
);
337 else if (charpos
< to
)
338 { /* Before-insertion markers will automatically move forward
339 upon re-inserting the deleted text, so we have to arrange
340 for them to move backward to the correct position. */
341 XSETMISC (marker
, m
);
342 record_marker_adjustment (marker
, to
- charpos
);
345 m
->bytepos
= from_byte
;
347 /* Here's the case where a before-insertion marker is immediately
348 before the deleted region. */
349 else if (charpos
== from
&& m
->insertion_type
)
351 /* Undoing the change uses normal insertion, which will
352 incorrectly make MARKER move forward, so we arrange for it
353 to then move backward to the correct place at the beginning
354 of the deleted region. */
355 XSETMISC (marker
, m
);
356 record_marker_adjustment (marker
, to
- from
);
362 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
363 to TO / TO_BYTE. We have to relocate the charpos of every marker
364 that points after the insertion (but not their bytepos).
366 When a marker points at the insertion point,
367 we advance it if either its insertion-type is t
368 or BEFORE_MARKERS is true. */
371 adjust_markers_for_insert (EMACS_INT from
, EMACS_INT from_byte
,
372 EMACS_INT to
, EMACS_INT to_byte
, int before_markers
)
374 struct Lisp_Marker
*m
;
376 EMACS_INT nchars
= to
- from
;
377 EMACS_INT nbytes
= to_byte
- from_byte
;
379 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
381 eassert (m
->bytepos
>= m
->charpos
382 && m
->bytepos
- m
->charpos
<= Z_BYTE
- Z
);
384 if (m
->bytepos
== from_byte
)
386 if (m
->insertion_type
|| before_markers
)
388 m
->bytepos
= to_byte
;
390 if (m
->insertion_type
)
394 else if (m
->bytepos
> from_byte
)
396 m
->bytepos
+= nbytes
;
397 m
->charpos
+= nchars
;
401 /* Adjusting only markers whose insertion-type is t may result in
402 - disordered start and end in overlays, and
403 - disordered overlays in the slot `overlays_before' of current_buffer. */
406 fix_start_end_in_overlays(from
, to
);
407 fix_overlays_before (current_buffer
, from
, to
);
411 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
413 This is used only when the value of point changes due to an insert
414 or delete; it does not represent a conceptual change in point as a
415 marker. In particular, point is not crossing any interval
416 boundaries, so there's no need to use the usual SET_PT macro. In
417 fact it would be incorrect to do so, because either the old or the
418 new value of point is out of sync with the current set of
422 adjust_point (EMACS_INT nchars
, EMACS_INT nbytes
)
424 BUF_PT (current_buffer
) += nchars
;
425 BUF_PT_BYTE (current_buffer
) += nbytes
;
427 /* In a single-byte buffer, the two positions must be equal. */
428 eassert (PT_BYTE
>= PT
&& PT_BYTE
- PT
<= ZV_BYTE
- ZV
);
431 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
432 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
433 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
437 adjust_markers_for_replace (EMACS_INT from
, EMACS_INT from_byte
,
438 EMACS_INT old_chars
, EMACS_INT old_bytes
,
439 EMACS_INT new_chars
, EMACS_INT new_bytes
)
441 register struct Lisp_Marker
*m
;
442 EMACS_INT prev_to_byte
= from_byte
+ old_bytes
;
443 EMACS_INT diff_chars
= new_chars
- old_chars
;
444 EMACS_INT diff_bytes
= new_bytes
- old_bytes
;
446 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
448 if (m
->bytepos
>= prev_to_byte
)
450 m
->charpos
+= diff_chars
;
451 m
->bytepos
+= diff_bytes
;
453 else if (m
->bytepos
> from_byte
)
456 m
->bytepos
= from_byte
;
464 /* Make the gap NBYTES_ADDED bytes longer. */
467 make_gap_larger (EMACS_INT nbytes_added
)
470 EMACS_INT real_gap_loc
;
471 EMACS_INT real_gap_loc_byte
;
472 EMACS_INT old_gap_size
;
474 /* If we have to get more space, get enough to last a while. */
475 nbytes_added
+= 2000;
477 { EMACS_INT total_size
= Z_BYTE
- BEG_BYTE
+ GAP_SIZE
+ nbytes_added
;
479 /* Don't allow a buffer size that won't fit in a Lisp integer. */
480 || total_size
!= XINT (make_number (total_size
))
481 /* Don't allow a buffer size that won't fit in an int
482 even if it will fit in a Lisp integer.
483 That won't work because so many places still use `int'. */
484 || total_size
!= (EMACS_INT
) (int) total_size
)
485 error ("Buffer exceeds maximum size");
488 enlarge_buffer_text (current_buffer
, nbytes_added
);
490 /* Prevent quitting in move_gap. */
495 real_gap_loc_byte
= GPT_BYTE
;
496 old_gap_size
= GAP_SIZE
;
498 /* Call the newly allocated space a gap at the end of the whole space. */
500 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
501 GAP_SIZE
= nbytes_added
;
503 /* Move the new gap down to be consecutive with the end of the old one.
504 This adjusts the markers properly too. */
505 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
507 /* Now combine the two into one large gap. */
508 GAP_SIZE
+= old_gap_size
;
510 GPT_BYTE
= real_gap_loc_byte
;
519 /* Make the gap NBYTES_REMOVED bytes shorter. */
522 make_gap_smaller (EMACS_INT nbytes_removed
)
525 EMACS_INT real_gap_loc
;
526 EMACS_INT real_gap_loc_byte
;
528 EMACS_INT real_Z_byte
;
529 EMACS_INT real_beg_unchanged
;
530 EMACS_INT new_gap_size
;
532 /* Make sure the gap is at least 20 bytes. */
533 if (GAP_SIZE
- nbytes_removed
< 20)
534 nbytes_removed
= GAP_SIZE
- 20;
536 /* Prevent quitting in move_gap. */
541 real_gap_loc_byte
= GPT_BYTE
;
542 new_gap_size
= GAP_SIZE
- nbytes_removed
;
544 real_Z_byte
= Z_BYTE
;
545 real_beg_unchanged
= BEG_UNCHANGED
;
547 /* Pretend that the last unwanted part of the gap is the entire gap,
548 and that the first desired part of the gap is part of the buffer
550 memset (GPT_ADDR
, 0, new_gap_size
);
552 GPT_BYTE
+= new_gap_size
;
554 Z_BYTE
+= new_gap_size
;
555 GAP_SIZE
= nbytes_removed
;
557 /* Move the unwanted pretend gap to the end of the buffer. This
558 adjusts the markers properly too. */
559 gap_right (Z
, Z_BYTE
);
561 enlarge_buffer_text (current_buffer
, -nbytes_removed
);
563 /* Now restore the desired gap. */
564 GAP_SIZE
= new_gap_size
;
566 GPT_BYTE
= real_gap_loc_byte
;
568 Z_BYTE
= real_Z_byte
;
569 BEG_UNCHANGED
= real_beg_unchanged
;
578 make_gap (EMACS_INT nbytes_added
)
580 if (nbytes_added
>= 0)
581 make_gap_larger (nbytes_added
);
582 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
584 make_gap_smaller (-nbytes_added
);
588 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
589 FROM_MULTIBYTE says whether the incoming text is multibyte.
590 TO_MULTIBYTE says whether to store the text as multibyte.
591 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
593 Return the number of bytes stored at TO_ADDR. */
596 copy_text (const unsigned char *from_addr
, unsigned char *to_addr
,
597 EMACS_INT nbytes
, int from_multibyte
, int to_multibyte
)
599 if (from_multibyte
== to_multibyte
)
601 memcpy (to_addr
, from_addr
, nbytes
);
604 else if (from_multibyte
)
606 EMACS_INT nchars
= 0;
607 EMACS_INT bytes_left
= nbytes
;
608 Lisp_Object tbl
= Qnil
;
610 while (bytes_left
> 0)
613 c
= STRING_CHAR_AND_LENGTH (from_addr
, thislen
);
614 if (! ASCII_CHAR_P (c
))
617 from_addr
+= thislen
;
618 bytes_left
-= thislen
;
625 unsigned char *initial_to_addr
= to_addr
;
627 /* Convert single-byte to multibyte. */
630 int c
= *from_addr
++;
632 if (!ASCII_CHAR_P (c
))
634 c
= BYTE8_TO_CHAR (c
);
635 to_addr
+= CHAR_STRING (c
, to_addr
);
639 /* Special case for speed. */
640 *to_addr
++ = c
, nbytes
--;
642 return to_addr
- initial_to_addr
;
646 /* Return the number of bytes it would take
647 to convert some single-byte text to multibyte.
648 The single-byte text consists of NBYTES bytes at PTR. */
651 count_size_as_multibyte (const unsigned char *ptr
, EMACS_INT nbytes
)
654 EMACS_INT outgoing_nbytes
= 0;
656 for (i
= 0; i
< nbytes
; i
++)
658 unsigned int c
= *ptr
++;
660 if (ASCII_CHAR_P (c
))
664 c
= BYTE8_TO_CHAR (c
);
665 outgoing_nbytes
+= CHAR_BYTES (c
);
669 return outgoing_nbytes
;
672 /* Insert a string of specified length before point.
673 This function judges multibyteness based on
674 enable_multibyte_characters in the current buffer;
675 it never converts between single-byte and multibyte.
677 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
678 prepare_to_modify_buffer could relocate the text. */
681 insert (const unsigned char *string
, EMACS_INT nbytes
)
685 EMACS_INT len
= chars_in_text (string
, nbytes
), opoint
;
686 insert_1_both (string
, len
, nbytes
, 0, 1, 0);
688 signal_after_change (opoint
, 0, len
);
689 update_compositions (opoint
, PT
, CHECK_BORDER
);
693 /* Likewise, but inherit text properties from neighboring characters. */
696 insert_and_inherit (const unsigned char *string
, EMACS_INT nbytes
)
700 EMACS_INT len
= chars_in_text (string
, nbytes
), opoint
;
701 insert_1_both (string
, len
, nbytes
, 1, 1, 0);
703 signal_after_change (opoint
, 0, len
);
704 update_compositions (opoint
, PT
, CHECK_BORDER
);
708 /* Insert the character C before point. Do not inherit text properties. */
713 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
716 if (! NILP (current_buffer
->enable_multibyte_characters
))
717 len
= CHAR_STRING (c
, str
);
727 /* Insert the null-terminated string S before point. */
730 insert_string (const char *s
)
732 insert (s
, strlen (s
));
735 /* Like `insert' except that all markers pointing at the place where
736 the insertion happens are adjusted to point after it.
737 Don't use this function to insert part of a Lisp string,
738 since gc could happen and relocate it. */
741 insert_before_markers (const unsigned char *string
, EMACS_INT nbytes
)
745 EMACS_INT len
= chars_in_text (string
, nbytes
), opoint
;
746 insert_1_both (string
, len
, nbytes
, 0, 1, 1);
748 signal_after_change (opoint
, 0, len
);
749 update_compositions (opoint
, PT
, CHECK_BORDER
);
753 /* Likewise, but inherit text properties from neighboring characters. */
756 insert_before_markers_and_inherit (const unsigned char *string
,
761 EMACS_INT len
= chars_in_text (string
, nbytes
), opoint
;
762 insert_1_both (string
, len
, nbytes
, 1, 1, 1);
764 signal_after_change (opoint
, 0, len
);
765 update_compositions (opoint
, PT
, CHECK_BORDER
);
769 /* Subroutine used by the insert functions above. */
772 insert_1 (const unsigned char *string
, EMACS_INT nbytes
,
773 int inherit
, int prepare
, int before_markers
)
775 insert_1_both (string
, chars_in_text (string
, nbytes
), nbytes
,
776 inherit
, prepare
, before_markers
);
780 #ifdef BYTE_COMBINING_DEBUG
782 /* See if the bytes before POS/POS_BYTE combine with bytes
783 at the start of STRING to form a single character.
784 If so, return the number of bytes at the start of STRING
785 which combine in this way. Otherwise, return 0. */
788 count_combining_before (const unsigned char *string
, EMACS_INT length
,
789 EMACS_INT pos
, EMACS_INT pos_byte
)
791 int len
, combining_bytes
;
792 const unsigned char *p
;
794 if (NILP (current_buffer
->enable_multibyte_characters
))
797 /* At first, we can exclude the following cases:
798 (1) STRING[0] can't be a following byte of multibyte sequence.
799 (2) POS is the start of the current buffer.
800 (3) A character before POS is not a multibyte character. */
801 if (length
== 0 || CHAR_HEAD_P (*string
)) /* case (1) */
803 if (pos_byte
== BEG_BYTE
) /* case (2) */
806 p
= BYTE_POS_ADDR (pos_byte
- 1);
807 while (! CHAR_HEAD_P (*p
)) p
--, len
++;
808 if (! LEADING_CODE_P (*p
)) /* case (3) */
811 combining_bytes
= BYTES_BY_CHAR_HEAD (*p
) - len
;
812 if (combining_bytes
<= 0)
813 /* The character preceding POS is, complete and no room for
814 combining bytes (combining_bytes == 0), or an independent 8-bit
815 character (combining_bytes < 0). */
818 /* We have a combination situation. Count the bytes at STRING that
821 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
824 return (combining_bytes
< p
- string
? combining_bytes
: p
- string
);
827 /* See if the bytes after POS/POS_BYTE combine with bytes
828 at the end of STRING to form a single character.
829 If so, return the number of bytes after POS/POS_BYTE
830 which combine in this way. Otherwise, return 0. */
833 count_combining_after (const unsigned char *string
,
834 EMACS_INT length
, EMACS_INT pos
, EMACS_INT pos_byte
)
836 EMACS_INT opos_byte
= pos_byte
;
841 if (NILP (current_buffer
->enable_multibyte_characters
))
844 /* At first, we can exclude the following cases:
845 (1) The last byte of STRING is an ASCII.
846 (2) POS is the last of the current buffer.
847 (3) A character at POS can't be a following byte of multibyte
849 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1])) /* case (1) */
851 if (pos_byte
== Z_BYTE
) /* case (2) */
853 bufp
= BYTE_POS_ADDR (pos_byte
);
854 if (CHAR_HEAD_P (*bufp
)) /* case (3) */
858 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
864 /* All characters in STRING are not character head. We must
865 check also preceding bytes at POS. We are sure that the gap
867 unsigned char *p
= BEG_ADDR
;
869 while (i
>= 0 && ! CHAR_HEAD_P (p
[i
]))
871 if (i
< 0 || !LEADING_CODE_P (p
[i
]))
874 bytes
= BYTES_BY_CHAR_HEAD (p
[i
]);
875 return (bytes
<= pos_byte
- 1 - i
+ length
877 : bytes
- (pos_byte
- 1 - i
+ length
));
879 if (!LEADING_CODE_P (string
[i
]))
882 bytes
= BYTES_BY_CHAR_HEAD (string
[i
]) - (length
- i
);
884 while (!CHAR_HEAD_P (*bufp
)) bufp
++, pos_byte
++;
886 return (bytes
<= pos_byte
- opos_byte
? bytes
: pos_byte
- opos_byte
);
892 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
893 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
894 are the same as in insert_1. */
897 insert_1_both (const unsigned char *string
,
898 EMACS_INT nchars
, EMACS_INT nbytes
,
899 int inherit
, int prepare
, int before_markers
)
904 if (NILP (current_buffer
->enable_multibyte_characters
))
908 /* Do this before moving and increasing the gap,
909 because the before-change hooks might move the gap
910 or make it smaller. */
911 prepare_to_modify_buffer (PT
, PT
, NULL
);
914 move_gap_both (PT
, PT_BYTE
);
915 if (GAP_SIZE
< nbytes
)
916 make_gap (nbytes
- GAP_SIZE
);
918 #ifdef BYTE_COMBINING_DEBUG
919 if (count_combining_before (string
, nbytes
, PT
, PT_BYTE
)
920 || count_combining_after (string
, nbytes
, PT
, PT_BYTE
))
924 /* Record deletion of the surrounding text that combines with
925 the insertion. This, together with recording the insertion,
926 will add up to the right stuff in the undo list. */
927 record_insert (PT
, nchars
);
929 CHARS_MODIFF
= MODIFF
;
931 memcpy (GPT_ADDR
, string
, nbytes
);
940 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
945 /* The insert may have been in the unchanged region, so check again. */
946 if (Z
- GPT
< END_UNCHANGED
)
947 END_UNCHANGED
= Z
- GPT
;
949 adjust_overlays_for_insert (PT
, nchars
);
950 adjust_markers_for_insert (PT
, PT_BYTE
,
951 PT
+ nchars
, PT_BYTE
+ nbytes
,
954 if (BUF_INTERVALS (current_buffer
) != 0)
955 offset_intervals (current_buffer
, PT
, nchars
);
957 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
958 set_text_properties (make_number (PT
), make_number (PT
+ nchars
),
961 adjust_point (nchars
, nbytes
);
966 /* Insert the part of the text of STRING, a Lisp object assumed to be
967 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
968 starting at position POS / POS_BYTE. If the text of STRING has properties,
969 copy them into the buffer.
971 It does not work to use `insert' for this, because a GC could happen
972 before we copy the stuff into the buffer, and relocate the string
973 without insert noticing. */
976 insert_from_string (Lisp_Object string
, EMACS_INT pos
, EMACS_INT pos_byte
,
977 EMACS_INT length
, EMACS_INT length_byte
, int inherit
)
979 EMACS_INT opoint
= PT
;
981 if (SCHARS (string
) == 0)
984 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
986 signal_after_change (opoint
, 0, PT
- opoint
);
987 update_compositions (opoint
, PT
, CHECK_BORDER
);
990 /* Like `insert_from_string' except that all markers pointing
991 at the place where the insertion happens are adjusted to point after it. */
994 insert_from_string_before_markers (Lisp_Object string
,
995 EMACS_INT pos
, EMACS_INT pos_byte
,
996 EMACS_INT length
, EMACS_INT length_byte
,
999 EMACS_INT opoint
= PT
;
1001 if (SCHARS (string
) == 0)
1004 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1006 signal_after_change (opoint
, 0, PT
- opoint
);
1007 update_compositions (opoint
, PT
, CHECK_BORDER
);
1010 /* Subroutine of the insertion functions above. */
1013 insert_from_string_1 (Lisp_Object string
, EMACS_INT pos
, EMACS_INT pos_byte
,
1014 EMACS_INT nchars
, EMACS_INT nbytes
,
1015 int inherit
, int before_markers
)
1017 struct gcpro gcpro1
;
1018 EMACS_INT outgoing_nbytes
= nbytes
;
1021 /* Make OUTGOING_NBYTES describe the text
1022 as it will be inserted in this buffer. */
1024 if (NILP (current_buffer
->enable_multibyte_characters
))
1025 outgoing_nbytes
= nchars
;
1026 else if (! STRING_MULTIBYTE (string
))
1028 = count_size_as_multibyte (SDATA (string
) + pos_byte
,
1032 /* Do this before moving and increasing the gap,
1033 because the before-change hooks might move the gap
1034 or make it smaller. */
1035 prepare_to_modify_buffer (PT
, PT
, NULL
);
1038 move_gap_both (PT
, PT_BYTE
);
1039 if (GAP_SIZE
< outgoing_nbytes
)
1040 make_gap (outgoing_nbytes
- GAP_SIZE
);
1043 /* Copy the string text into the buffer, perhaps converting
1044 between single-byte and multibyte. */
1045 copy_text (SDATA (string
) + pos_byte
, GPT_ADDR
, nbytes
,
1046 STRING_MULTIBYTE (string
),
1047 ! NILP (current_buffer
->enable_multibyte_characters
));
1049 #ifdef BYTE_COMBINING_DEBUG
1050 /* We have copied text into the gap, but we have not altered
1051 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1052 to these functions and get the same results as we would
1053 have got earlier on. Meanwhile, PT_ADDR does point to
1054 the text that has been stored by copy_text. */
1055 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1056 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1060 record_insert (PT
, nchars
);
1062 CHARS_MODIFF
= MODIFF
;
1064 GAP_SIZE
-= outgoing_nbytes
;
1068 GPT_BYTE
+= outgoing_nbytes
;
1069 ZV_BYTE
+= outgoing_nbytes
;
1070 Z_BYTE
+= outgoing_nbytes
;
1071 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1076 /* The insert may have been in the unchanged region, so check again. */
1077 if (Z
- GPT
< END_UNCHANGED
)
1078 END_UNCHANGED
= Z
- GPT
;
1080 adjust_overlays_for_insert (PT
, nchars
);
1081 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1082 PT_BYTE
+ outgoing_nbytes
,
1085 offset_intervals (current_buffer
, PT
, nchars
);
1087 intervals
= STRING_INTERVALS (string
);
1088 /* Get the intervals for the part of the string we are inserting. */
1089 if (nbytes
< SBYTES (string
))
1090 intervals
= copy_intervals (intervals
, pos
, nchars
);
1092 /* Insert those intervals. */
1093 graft_intervals_into_buffer (intervals
, PT
, nchars
,
1094 current_buffer
, inherit
);
1096 adjust_point (nchars
, outgoing_nbytes
);
1101 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1102 starting at GPT_ADDR. */
1105 insert_from_gap (EMACS_INT nchars
, EMACS_INT nbytes
)
1107 if (NILP (current_buffer
->enable_multibyte_characters
))
1110 record_insert (GPT
, nchars
);
1120 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1125 adjust_overlays_for_insert (GPT
- nchars
, nchars
);
1126 adjust_markers_for_insert (GPT
- nchars
, GPT_BYTE
- nbytes
,
1129 if (BUF_INTERVALS (current_buffer
) != 0)
1131 offset_intervals (current_buffer
, GPT
- nchars
, nchars
);
1132 graft_intervals_into_buffer (NULL_INTERVAL
, GPT
- nchars
, nchars
,
1136 if (GPT
- nchars
< PT
)
1137 adjust_point (nchars
, nbytes
);
1142 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1143 current buffer. If the text in BUF has properties, they are absorbed
1144 into the current buffer.
1146 It does not work to use `insert' for this, because a malloc could happen
1147 and relocate BUF's text before the copy happens. */
1150 insert_from_buffer (struct buffer
*buf
,
1151 EMACS_INT charpos
, EMACS_INT nchars
, int inherit
)
1153 EMACS_INT opoint
= PT
;
1155 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1156 signal_after_change (opoint
, 0, PT
- opoint
);
1157 update_compositions (opoint
, PT
, CHECK_BORDER
);
1161 insert_from_buffer_1 (struct buffer
*buf
,
1162 EMACS_INT from
, EMACS_INT nchars
, int inherit
)
1164 register Lisp_Object temp
;
1165 EMACS_INT chunk
, chunk_expanded
;
1166 EMACS_INT from_byte
= buf_charpos_to_bytepos (buf
, from
);
1167 EMACS_INT to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1168 EMACS_INT incoming_nbytes
= to_byte
- from_byte
;
1169 EMACS_INT outgoing_nbytes
= incoming_nbytes
;
1172 /* Make OUTGOING_NBYTES describe the text
1173 as it will be inserted in this buffer. */
1175 if (NILP (current_buffer
->enable_multibyte_characters
))
1176 outgoing_nbytes
= nchars
;
1177 else if (NILP (buf
->enable_multibyte_characters
))
1179 EMACS_INT outgoing_before_gap
= 0;
1180 EMACS_INT outgoing_after_gap
= 0;
1182 if (from
< BUF_GPT (buf
))
1184 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1185 if (chunk
> incoming_nbytes
)
1186 chunk
= incoming_nbytes
;
1188 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1194 if (chunk
< incoming_nbytes
)
1196 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
,
1198 incoming_nbytes
- chunk
);
1200 outgoing_nbytes
= outgoing_before_gap
+ outgoing_after_gap
;
1203 /* Make sure point-max won't overflow after this insertion. */
1204 XSETINT (temp
, outgoing_nbytes
+ Z
);
1205 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1206 error ("Maximum buffer size exceeded");
1208 /* Do this before moving and increasing the gap,
1209 because the before-change hooks might move the gap
1210 or make it smaller. */
1211 prepare_to_modify_buffer (PT
, PT
, NULL
);
1214 move_gap_both (PT
, PT_BYTE
);
1215 if (GAP_SIZE
< outgoing_nbytes
)
1216 make_gap (outgoing_nbytes
- GAP_SIZE
);
1218 if (from
< BUF_GPT (buf
))
1220 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1221 if (chunk
> incoming_nbytes
)
1222 chunk
= incoming_nbytes
;
1223 /* Record number of output bytes, so we know where
1224 to put the output from the second copy_text. */
1226 = copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1228 ! NILP (buf
->enable_multibyte_characters
),
1229 ! NILP (current_buffer
->enable_multibyte_characters
));
1232 chunk_expanded
= chunk
= 0;
1234 if (chunk
< incoming_nbytes
)
1235 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1236 GPT_ADDR
+ chunk_expanded
, incoming_nbytes
- chunk
,
1237 ! NILP (buf
->enable_multibyte_characters
),
1238 ! NILP (current_buffer
->enable_multibyte_characters
));
1240 #ifdef BYTE_COMBINING_DEBUG
1241 /* We have copied text into the gap, but we have not altered
1242 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1243 to these functions and get the same results as we would
1244 have got earlier on. Meanwhile, GPT_ADDR does point to
1245 the text that has been stored by copy_text. */
1246 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1247 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1251 record_insert (PT
, nchars
);
1253 CHARS_MODIFF
= MODIFF
;
1255 GAP_SIZE
-= outgoing_nbytes
;
1259 GPT_BYTE
+= outgoing_nbytes
;
1260 ZV_BYTE
+= outgoing_nbytes
;
1261 Z_BYTE
+= outgoing_nbytes
;
1262 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1267 /* The insert may have been in the unchanged region, so check again. */
1268 if (Z
- GPT
< END_UNCHANGED
)
1269 END_UNCHANGED
= Z
- GPT
;
1271 adjust_overlays_for_insert (PT
, nchars
);
1272 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1273 PT_BYTE
+ outgoing_nbytes
,
1276 if (BUF_INTERVALS (current_buffer
) != 0)
1277 offset_intervals (current_buffer
, PT
, nchars
);
1279 /* Get the intervals for the part of the string we are inserting. */
1280 intervals
= BUF_INTERVALS (buf
);
1281 if (nchars
< BUF_Z (buf
) - BUF_BEG (buf
))
1283 if (buf
== current_buffer
&& PT
<= from
)
1285 intervals
= copy_intervals (intervals
, from
, nchars
);
1288 /* Insert those intervals. */
1289 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1291 adjust_point (nchars
, outgoing_nbytes
);
1294 /* Record undo information and adjust markers and position keepers for
1295 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1296 chars (LEN_BYTE bytes) which resides in the gap just after
1299 PREV_TEXT nil means the new text was just inserted. */
1302 adjust_after_replace (EMACS_INT from
, EMACS_INT from_byte
,
1303 Lisp_Object prev_text
, EMACS_INT len
, EMACS_INT len_byte
)
1305 EMACS_INT nchars_del
= 0, nbytes_del
= 0;
1307 #ifdef BYTE_COMBINING_DEBUG
1308 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1309 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1313 if (STRINGP (prev_text
))
1315 nchars_del
= SCHARS (prev_text
);
1316 nbytes_del
= SBYTES (prev_text
);
1319 /* Update various buffer positions for the new text. */
1320 GAP_SIZE
-= len_byte
;
1322 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1323 GPT
+= len
; GPT_BYTE
+= len_byte
;
1324 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1327 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1330 adjust_markers_for_insert (from
, from_byte
,
1331 from
+ len
, from_byte
+ len_byte
, 0);
1333 if (! EQ (current_buffer
->undo_list
, Qt
))
1336 record_delete (from
, prev_text
);
1337 record_insert (from
, len
);
1340 if (len
> nchars_del
)
1341 adjust_overlays_for_insert (from
, len
- nchars_del
);
1342 else if (len
< nchars_del
)
1343 adjust_overlays_for_delete (from
, nchars_del
- len
);
1344 if (BUF_INTERVALS (current_buffer
) != 0)
1346 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1350 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1352 /* As byte combining will decrease Z, we must check this again. */
1353 if (Z
- GPT
< END_UNCHANGED
)
1354 END_UNCHANGED
= Z
- GPT
;
1359 evaporate_overlays (from
);
1361 CHARS_MODIFF
= MODIFF
;
1364 /* Like adjust_after_replace, but doesn't require PREV_TEXT.
1365 This is for use when undo is not enabled in the current buffer. */
1368 adjust_after_replace_noundo (EMACS_INT from
, EMACS_INT from_byte
,
1369 EMACS_INT nchars_del
, EMACS_INT nbytes_del
,
1370 EMACS_INT len
, EMACS_INT len_byte
)
1372 #ifdef BYTE_COMBINING_DEBUG
1373 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1374 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1378 /* Update various buffer positions for the new text. */
1379 GAP_SIZE
-= len_byte
;
1381 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1382 GPT
+= len
; GPT_BYTE
+= len_byte
;
1383 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1386 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1389 adjust_markers_for_insert (from
, from_byte
,
1390 from
+ len
, from_byte
+ len_byte
, 0);
1392 if (len
> nchars_del
)
1393 adjust_overlays_for_insert (from
, len
- nchars_del
);
1394 else if (len
< nchars_del
)
1395 adjust_overlays_for_delete (from
, nchars_del
- len
);
1396 if (BUF_INTERVALS (current_buffer
) != 0)
1398 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1402 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1404 /* As byte combining will decrease Z, we must check this again. */
1405 if (Z
- GPT
< END_UNCHANGED
)
1406 END_UNCHANGED
= Z
- GPT
;
1411 evaporate_overlays (from
);
1413 CHARS_MODIFF
= MODIFF
;
1416 /* Record undo information, adjust markers and position keepers for an
1417 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1418 text already exists in the current buffer but character length (TO
1419 - FROM) may be incorrect, the correct length is NEWLEN. */
1422 adjust_after_insert (EMACS_INT from
, EMACS_INT from_byte
,
1423 EMACS_INT to
, EMACS_INT to_byte
, EMACS_INT newlen
)
1425 EMACS_INT len
= to
- from
, len_byte
= to_byte
- from_byte
;
1428 move_gap_both (to
, to_byte
);
1429 GAP_SIZE
+= len_byte
;
1430 GPT
-= len
; GPT_BYTE
-= len_byte
;
1431 ZV
-= len
; ZV_BYTE
-= len_byte
;
1432 Z
-= len
; Z_BYTE
-= len_byte
;
1433 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1436 /* Replace the text from character positions FROM to TO with NEW,
1437 If PREPARE is nonzero, call prepare_to_modify_buffer.
1438 If INHERIT, the newly inserted text should inherit text properties
1439 from the surrounding non-deleted text. */
1441 /* Note that this does not yet handle markers quite right.
1442 Also it needs to record a single undo-entry that does a replacement
1443 rather than a separate delete and insert.
1444 That way, undo will also handle markers properly.
1446 But if MARKERS is 0, don't relocate markers. */
1449 replace_range (EMACS_INT from
, EMACS_INT to
, Lisp_Object
new,
1450 int prepare
, int inherit
, int markers
)
1452 EMACS_INT inschars
= SCHARS (new);
1453 EMACS_INT insbytes
= SBYTES (new);
1454 EMACS_INT from_byte
, to_byte
;
1455 EMACS_INT nbytes_del
, nchars_del
;
1456 register Lisp_Object temp
;
1457 struct gcpro gcpro1
;
1459 EMACS_INT outgoing_insbytes
= insbytes
;
1460 Lisp_Object deletion
;
1469 EMACS_INT range_length
= to
- from
;
1470 prepare_to_modify_buffer (from
, to
, &from
);
1471 to
= from
+ range_length
;
1476 /* Make args be valid */
1482 from_byte
= CHAR_TO_BYTE (from
);
1483 to_byte
= CHAR_TO_BYTE (to
);
1485 nchars_del
= to
- from
;
1486 nbytes_del
= to_byte
- from_byte
;
1488 if (nbytes_del
<= 0 && insbytes
== 0)
1491 /* Make OUTGOING_INSBYTES describe the text
1492 as it will be inserted in this buffer. */
1494 if (NILP (current_buffer
->enable_multibyte_characters
))
1495 outgoing_insbytes
= inschars
;
1496 else if (! STRING_MULTIBYTE (new))
1498 = count_size_as_multibyte (SDATA (new), insbytes
);
1500 /* Make sure point-max won't overflow after this insertion. */
1501 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1502 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1503 error ("Maximum buffer size exceeded");
1507 /* Make sure the gap is somewhere in or next to what we are deleting. */
1509 gap_right (from
, from_byte
);
1511 gap_left (to
, to_byte
, 0);
1513 /* Even if we don't record for undo, we must keep the original text
1514 because we may have to recover it because of inappropriate byte
1516 if (! EQ (current_buffer
->undo_list
, Qt
))
1517 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1519 GAP_SIZE
+= nbytes_del
;
1522 ZV_BYTE
-= nbytes_del
;
1523 Z_BYTE
-= nbytes_del
;
1525 GPT_BYTE
= from_byte
;
1526 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1531 if (GPT
- BEG
< BEG_UNCHANGED
)
1532 BEG_UNCHANGED
= GPT
- BEG
;
1533 if (Z
- GPT
< END_UNCHANGED
)
1534 END_UNCHANGED
= Z
- GPT
;
1536 if (GAP_SIZE
< insbytes
)
1537 make_gap (insbytes
- GAP_SIZE
);
1539 /* Copy the string text into the buffer, perhaps converting
1540 between single-byte and multibyte. */
1541 copy_text (SDATA (new), GPT_ADDR
, insbytes
,
1542 STRING_MULTIBYTE (new),
1543 ! NILP (current_buffer
->enable_multibyte_characters
));
1545 #ifdef BYTE_COMBINING_DEBUG
1546 /* We have copied text into the gap, but we have not marked
1547 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1548 here, for both the previous text and the following text.
1549 Meanwhile, GPT_ADDR does point to
1550 the text that has been stored by copy_text. */
1551 if (count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
)
1552 || count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
))
1556 if (! EQ (current_buffer
->undo_list
, Qt
))
1558 /* Record the insertion first, so that when we undo,
1559 the deletion will be undone first. Thus, undo
1560 will insert before deleting, and thus will keep
1561 the markers before and after this text separate. */
1562 record_insert (from
+ SCHARS (deletion
), inschars
);
1563 record_delete (from
, deletion
);
1566 GAP_SIZE
-= outgoing_insbytes
;
1570 GPT_BYTE
+= outgoing_insbytes
;
1571 ZV_BYTE
+= outgoing_insbytes
;
1572 Z_BYTE
+= outgoing_insbytes
;
1573 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1578 /* Adjust the overlay center as needed. This must be done after
1579 adjusting the markers that bound the overlays. */
1580 adjust_overlays_for_delete (from
, nchars_del
);
1581 adjust_overlays_for_insert (from
, inschars
);
1583 /* Adjust markers for the deletion and the insertion. */
1585 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1586 inschars
, outgoing_insbytes
);
1588 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1590 /* Get the intervals for the part of the string we are inserting--
1591 not including the combined-before bytes. */
1592 intervals
= STRING_INTERVALS (new);
1593 /* Insert those intervals. */
1594 graft_intervals_into_buffer (intervals
, from
, inschars
,
1595 current_buffer
, inherit
);
1597 /* Relocate point as if it were a marker. */
1599 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1600 (from_byte
+ outgoing_insbytes
1601 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1603 if (outgoing_insbytes
== 0)
1604 evaporate_overlays (from
);
1609 CHARS_MODIFF
= MODIFF
;
1612 signal_after_change (from
, nchars_del
, GPT
- from
);
1613 update_compositions (from
, GPT
, CHECK_BORDER
);
1616 /* Replace the text from character positions FROM to TO with
1617 the text in INS of length INSCHARS.
1618 Keep the text properties that applied to the old characters
1619 (extending them to all the new chars if there are more new chars).
1621 Note that this does not yet handle markers quite right.
1623 If MARKERS is nonzero, relocate markers.
1625 Unlike most functions at this level, never call
1626 prepare_to_modify_buffer and never call signal_after_change. */
1629 replace_range_2 (EMACS_INT from
, EMACS_INT from_byte
,
1630 EMACS_INT to
, EMACS_INT to_byte
,
1631 const char *ins
, EMACS_INT inschars
, EMACS_INT insbytes
,
1634 EMACS_INT nbytes_del
, nchars_del
;
1639 nchars_del
= to
- from
;
1640 nbytes_del
= to_byte
- from_byte
;
1642 if (nbytes_del
<= 0 && insbytes
== 0)
1645 /* Make sure point-max won't overflow after this insertion. */
1646 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1647 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1648 error ("Maximum buffer size exceeded");
1650 /* Make sure the gap is somewhere in or next to what we are deleting. */
1652 gap_right (from
, from_byte
);
1654 gap_left (to
, to_byte
, 0);
1656 GAP_SIZE
+= nbytes_del
;
1659 ZV_BYTE
-= nbytes_del
;
1660 Z_BYTE
-= nbytes_del
;
1662 GPT_BYTE
= from_byte
;
1663 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1668 if (GPT
- BEG
< BEG_UNCHANGED
)
1669 BEG_UNCHANGED
= GPT
- BEG
;
1670 if (Z
- GPT
< END_UNCHANGED
)
1671 END_UNCHANGED
= Z
- GPT
;
1673 if (GAP_SIZE
< insbytes
)
1674 make_gap (insbytes
- GAP_SIZE
);
1676 /* Copy the replacement text into the buffer. */
1677 memcpy (GPT_ADDR
, ins
, insbytes
);
1679 #ifdef BYTE_COMBINING_DEBUG
1680 /* We have copied text into the gap, but we have not marked
1681 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1682 here, for both the previous text and the following text.
1683 Meanwhile, GPT_ADDR does point to
1684 the text that has been stored by copy_text. */
1685 if (count_combining_before (GPT_ADDR
, insbytes
, from
, from_byte
)
1686 || count_combining_after (GPT_ADDR
, insbytes
, from
, from_byte
))
1690 GAP_SIZE
-= insbytes
;
1694 GPT_BYTE
+= insbytes
;
1695 ZV_BYTE
+= insbytes
;
1697 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1702 /* Adjust the overlay center as needed. This must be done after
1703 adjusting the markers that bound the overlays. */
1704 if (nchars_del
!= inschars
)
1706 adjust_overlays_for_insert (from
, inschars
);
1707 adjust_overlays_for_delete (from
+ inschars
, nchars_del
);
1710 /* Adjust markers for the deletion and the insertion. */
1712 && ! (nchars_del
== 1 && inschars
== 1 && nbytes_del
== insbytes
))
1713 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1714 inschars
, insbytes
);
1716 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1718 /* Relocate point as if it were a marker. */
1719 if (from
< PT
&& (nchars_del
!= inschars
|| nbytes_del
!= insbytes
))
1722 /* PT was within the deleted text. Move it to FROM. */
1723 adjust_point (from
- PT
, from_byte
- PT_BYTE
);
1725 adjust_point (inschars
- nchars_del
, insbytes
- nbytes_del
);
1729 evaporate_overlays (from
);
1734 CHARS_MODIFF
= MODIFF
;
1737 /* Delete characters in current buffer
1738 from FROM up to (but not including) TO.
1739 If TO comes before FROM, we delete nothing. */
1742 del_range (EMACS_INT from
, EMACS_INT to
)
1744 del_range_1 (from
, to
, 1, 0);
1747 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1748 RET_STRING says to return the deleted text. */
1751 del_range_1 (EMACS_INT from
, EMACS_INT to
, int prepare
, int ret_string
)
1753 EMACS_INT from_byte
, to_byte
;
1754 Lisp_Object deletion
;
1755 struct gcpro gcpro1
;
1757 /* Make args be valid */
1768 EMACS_INT range_length
= to
- from
;
1769 prepare_to_modify_buffer (from
, to
, &from
);
1770 to
= min (ZV
, from
+ range_length
);
1773 from_byte
= CHAR_TO_BYTE (from
);
1774 to_byte
= CHAR_TO_BYTE (to
);
1776 deletion
= del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
);
1778 signal_after_change (from
, to
- from
, 0);
1779 update_compositions (from
, from
, CHECK_HEAD
);
1784 /* Like del_range_1 but args are byte positions, not char positions. */
1787 del_range_byte (EMACS_INT from_byte
, EMACS_INT to_byte
, int prepare
)
1791 /* Make args be valid */
1792 if (from_byte
< BEGV_BYTE
)
1793 from_byte
= BEGV_BYTE
;
1794 if (to_byte
> ZV_BYTE
)
1797 if (to_byte
<= from_byte
)
1800 from
= BYTE_TO_CHAR (from_byte
);
1801 to
= BYTE_TO_CHAR (to_byte
);
1805 EMACS_INT old_from
= from
, old_to
= Z
- to
;
1806 EMACS_INT range_length
= to
- from
;
1807 prepare_to_modify_buffer (from
, to
, &from
);
1808 to
= from
+ range_length
;
1810 if (old_from
!= from
)
1811 from_byte
= CHAR_TO_BYTE (from
);
1817 else if (old_to
== Z
- to
)
1818 to_byte
= CHAR_TO_BYTE (to
);
1821 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1822 signal_after_change (from
, to
- from
, 0);
1823 update_compositions (from
, from
, CHECK_HEAD
);
1826 /* Like del_range_1, but positions are specified both as charpos
1830 del_range_both (EMACS_INT from
, EMACS_INT from_byte
,
1831 EMACS_INT to
, EMACS_INT to_byte
, int prepare
)
1833 /* Make args be valid */
1834 if (from_byte
< BEGV_BYTE
)
1835 from_byte
= BEGV_BYTE
;
1836 if (to_byte
> ZV_BYTE
)
1839 if (to_byte
<= from_byte
)
1849 EMACS_INT old_from
= from
, old_to
= Z
- to
;
1850 EMACS_INT range_length
= to
- from
;
1851 prepare_to_modify_buffer (from
, to
, &from
);
1852 to
= from
+ range_length
;
1854 if (old_from
!= from
)
1855 from_byte
= CHAR_TO_BYTE (from
);
1861 else if (old_to
== Z
- to
)
1862 to_byte
= CHAR_TO_BYTE (to
);
1865 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1866 signal_after_change (from
, to
- from
, 0);
1867 update_compositions (from
, from
, CHECK_HEAD
);
1870 /* Delete a range of text, specified both as character positions
1871 and byte positions. FROM and TO are character positions,
1872 while FROM_BYTE and TO_BYTE are byte positions.
1873 If RET_STRING is true, the deleted area is returned as a string. */
1876 del_range_2 (EMACS_INT from
, EMACS_INT from_byte
,
1877 EMACS_INT to
, EMACS_INT to_byte
, int ret_string
)
1879 register EMACS_INT nbytes_del
, nchars_del
;
1880 Lisp_Object deletion
;
1884 nchars_del
= to
- from
;
1885 nbytes_del
= to_byte
- from_byte
;
1887 /* Make sure the gap is somewhere in or next to what we are deleting. */
1889 gap_right (from
, from_byte
);
1891 gap_left (to
, to_byte
, 0);
1893 #ifdef BYTE_COMBINING_DEBUG
1894 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
1895 Z_BYTE
- to_byte
, from
, from_byte
))
1899 if (ret_string
|| ! EQ (current_buffer
->undo_list
, Qt
))
1900 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1904 /* Relocate all markers pointing into the new, larger gap
1905 to point at the end of the text before the gap.
1906 Do this before recording the deletion,
1907 so that undo handles this after reinserting the text. */
1908 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1910 if (! EQ (current_buffer
->undo_list
, Qt
))
1911 record_delete (from
, deletion
);
1913 CHARS_MODIFF
= MODIFF
;
1915 /* Relocate point as if it were a marker. */
1917 adjust_point (from
- (PT
< to
? PT
: to
),
1918 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
1920 offset_intervals (current_buffer
, from
, - nchars_del
);
1922 /* Adjust the overlay center as needed. This must be done after
1923 adjusting the markers that bound the overlays. */
1924 adjust_overlays_for_delete (from
, nchars_del
);
1926 GAP_SIZE
+= nbytes_del
;
1927 ZV_BYTE
-= nbytes_del
;
1928 Z_BYTE
-= nbytes_del
;
1932 GPT_BYTE
= from_byte
;
1933 if (GAP_SIZE
> 0 && !current_buffer
->text
->inhibit_shrinking
)
1934 /* Put an anchor, unless called from decode_coding_object which
1935 needs to access the previous gap contents. */
1941 if (GPT
- BEG
< BEG_UNCHANGED
)
1942 BEG_UNCHANGED
= GPT
- BEG
;
1943 if (Z
- GPT
< END_UNCHANGED
)
1944 END_UNCHANGED
= Z
- GPT
;
1948 evaporate_overlays (from
);
1953 /* Call this if you're about to change the region of BUFFER from
1954 character positions START to END. This checks the read-only
1955 properties of the region, calls the necessary modification hooks,
1956 and warns the next redisplay that it should pay attention to that
1959 If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
1960 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1963 modify_region (struct buffer
*buffer
, EMACS_INT start
, EMACS_INT end
,
1964 int preserve_chars_modiff
)
1966 struct buffer
*old_buffer
= current_buffer
;
1968 if (buffer
!= old_buffer
)
1969 set_buffer_internal (buffer
);
1971 prepare_to_modify_buffer (start
, end
, NULL
);
1973 BUF_COMPUTE_UNCHANGED (buffer
, start
- 1, end
);
1975 if (MODIFF
<= SAVE_MODIFF
)
1976 record_first_change ();
1978 if (! preserve_chars_modiff
)
1979 CHARS_MODIFF
= MODIFF
;
1981 buffer
->point_before_scroll
= Qnil
;
1983 if (buffer
!= old_buffer
)
1984 set_buffer_internal (old_buffer
);
1987 /* Check that it is okay to modify the buffer between START and END,
1988 which are char positions.
1990 Run the before-change-function, if any. If intervals are in use,
1991 verify that the text to be modified is not read-only, and call
1992 any modification properties the text may have.
1994 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1995 by holding its value temporarily in a marker. */
1998 prepare_to_modify_buffer (EMACS_INT start
, EMACS_INT end
,
1999 EMACS_INT
*preserve_ptr
)
2001 struct buffer
*base_buffer
;
2003 if (!NILP (current_buffer
->read_only
))
2004 Fbarf_if_buffer_read_only ();
2006 /* Let redisplay consider other windows than selected_window
2007 if modifying another buffer. */
2008 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
2009 ++windows_or_buffers_changed
;
2011 if (BUF_INTERVALS (current_buffer
) != 0)
2015 Lisp_Object preserve_marker
;
2016 struct gcpro gcpro1
;
2017 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
2018 GCPRO1 (preserve_marker
);
2019 verify_interval_modification (current_buffer
, start
, end
);
2020 *preserve_ptr
= marker_position (preserve_marker
);
2021 unchain_marker (XMARKER (preserve_marker
));
2025 verify_interval_modification (current_buffer
, start
, end
);
2028 /* For indirect buffers, use the base buffer to check clashes. */
2029 if (current_buffer
->base_buffer
!= 0)
2030 base_buffer
= current_buffer
->base_buffer
;
2032 base_buffer
= current_buffer
;
2034 #ifdef CLASH_DETECTION
2035 if (!NILP (base_buffer
->file_truename
)
2036 /* Make binding buffer-file-name to nil effective. */
2037 && !NILP (base_buffer
->filename
)
2038 && SAVE_MODIFF
>= MODIFF
)
2039 lock_file (base_buffer
->file_truename
);
2041 /* At least warn if this file has changed on disk since it was visited. */
2042 if (!NILP (base_buffer
->filename
)
2043 && SAVE_MODIFF
>= MODIFF
2044 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2045 && !NILP (Ffile_exists_p (base_buffer
->filename
)))
2046 call1 (intern ("ask-user-about-supersession-threat"),
2047 base_buffer
->filename
);
2048 #endif /* not CLASH_DETECTION */
2050 signal_before_change (start
, end
, preserve_ptr
);
2052 if (current_buffer
->newline_cache
)
2053 invalidate_region_cache (current_buffer
,
2054 current_buffer
->newline_cache
,
2055 start
- BEG
, Z
- end
);
2056 if (current_buffer
->width_run_cache
)
2057 invalidate_region_cache (current_buffer
,
2058 current_buffer
->width_run_cache
,
2059 start
- BEG
, Z
- end
);
2061 Vdeactivate_mark
= Qt
;
2064 /* These macros work with an argument named `preserve_ptr'
2065 and a local variable named `preserve_marker'. */
2067 #define PRESERVE_VALUE \
2068 if (preserve_ptr && NILP (preserve_marker)) \
2069 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2071 #define RESTORE_VALUE \
2072 if (! NILP (preserve_marker)) \
2074 *preserve_ptr = marker_position (preserve_marker); \
2075 unchain_marker (XMARKER (preserve_marker)); \
2078 #define PRESERVE_START_END \
2079 if (NILP (start_marker)) \
2080 start_marker = Fcopy_marker (start, Qnil); \
2081 if (NILP (end_marker)) \
2082 end_marker = Fcopy_marker (end, Qnil);
2084 #define FETCH_START \
2085 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2088 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2090 /* Set a variable to nil if an error occurred.
2091 Don't change the variable if there was no error.
2092 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
2093 VARIABLE is the variable to maybe set to nil.
2094 NO-ERROR-FLAG is nil if there was an error,
2095 anything else meaning no error (so this function does nothing). */
2097 reset_var_on_error (Lisp_Object val
)
2099 if (NILP (XCDR (val
)))
2100 Fset (XCAR (val
), Qnil
);
2104 /* Signal a change to the buffer immediately before it happens.
2105 START_INT and END_INT are the bounds of the text to be changed.
2107 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2108 by holding its value temporarily in a marker. */
2111 signal_before_change (EMACS_INT start_int
, EMACS_INT end_int
,
2112 EMACS_INT
*preserve_ptr
)
2114 Lisp_Object start
, end
;
2115 Lisp_Object start_marker
, end_marker
;
2116 Lisp_Object preserve_marker
;
2117 struct gcpro gcpro1
, gcpro2
, gcpro3
;
2118 int count
= SPECPDL_INDEX ();
2120 if (inhibit_modification_hooks
)
2123 start
= make_number (start_int
);
2124 end
= make_number (end_int
);
2125 preserve_marker
= Qnil
;
2126 start_marker
= Qnil
;
2128 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
2130 specbind (Qinhibit_modification_hooks
, Qt
);
2132 /* If buffer is unmodified, run a special hook for that case. */
2133 if (SAVE_MODIFF
>= MODIFF
2134 && !NILP (Vfirst_change_hook
)
2135 && !NILP (Vrun_hooks
))
2139 call1 (Vrun_hooks
, Qfirst_change_hook
);
2142 /* Now run the before-change-functions if any. */
2143 if (!NILP (Vbefore_change_functions
))
2145 Lisp_Object args
[3];
2146 Lisp_Object rvoe_arg
= Fcons (Qbefore_change_functions
, Qnil
);
2151 /* Mark before-change-functions to be reset to nil in case of error. */
2152 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2154 /* Actually run the hook functions. */
2155 args
[0] = Qbefore_change_functions
;
2156 args
[1] = FETCH_START
;
2157 args
[2] = FETCH_END
;
2158 Frun_hook_with_args (3, args
);
2160 /* There was no error: unarm the reset_on_error. */
2161 XSETCDR (rvoe_arg
, Qt
);
2164 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2167 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2168 FETCH_START
, FETCH_END
, Qnil
);
2171 if (! NILP (start_marker
))
2172 free_marker (start_marker
);
2173 if (! NILP (end_marker
))
2174 free_marker (end_marker
);
2178 unbind_to (count
, Qnil
);
2181 /* Signal a change immediately after it happens.
2182 CHARPOS is the character position of the start of the changed text.
2183 LENDEL is the number of characters of the text before the change.
2184 (Not the whole buffer; just the part that was changed.)
2185 LENINS is the number of characters in that part of the text
2186 after the change. */
2189 signal_after_change (EMACS_INT charpos
, EMACS_INT lendel
, EMACS_INT lenins
)
2191 int count
= SPECPDL_INDEX ();
2192 if (inhibit_modification_hooks
)
2195 /* If we are deferring calls to the after-change functions
2196 and there are no before-change functions,
2197 just record the args that we were going to use. */
2198 if (! NILP (Vcombine_after_change_calls
)
2199 && NILP (Vbefore_change_functions
)
2200 && !current_buffer
->overlays_before
2201 && !current_buffer
->overlays_after
)
2205 if (!NILP (combine_after_change_list
)
2206 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2207 Fcombine_after_change_execute ();
2209 elt
= Fcons (make_number (charpos
- BEG
),
2210 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2211 Fcons (make_number (lenins
- lendel
), Qnil
)));
2212 combine_after_change_list
2213 = Fcons (elt
, combine_after_change_list
);
2214 combine_after_change_buffer
= Fcurrent_buffer ();
2219 if (!NILP (combine_after_change_list
))
2220 Fcombine_after_change_execute ();
2222 specbind (Qinhibit_modification_hooks
, Qt
);
2224 if (!NILP (Vafter_change_functions
))
2226 Lisp_Object args
[4];
2227 Lisp_Object rvoe_arg
= Fcons (Qafter_change_functions
, Qnil
);
2229 /* Mark after-change-functions to be reset to nil in case of error. */
2230 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2232 /* Actually run the hook functions. */
2233 args
[0] = Qafter_change_functions
;
2234 XSETFASTINT (args
[1], charpos
);
2235 XSETFASTINT (args
[2], charpos
+ lenins
);
2236 XSETFASTINT (args
[3], lendel
);
2237 Frun_hook_with_args (4, args
);
2239 /* There was no error: unarm the reset_on_error. */
2240 XSETCDR (rvoe_arg
, Qt
);
2243 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2244 report_overlay_modification (make_number (charpos
),
2245 make_number (charpos
+ lenins
),
2247 make_number (charpos
),
2248 make_number (charpos
+ lenins
),
2249 make_number (lendel
));
2251 /* After an insertion, call the text properties
2252 insert-behind-hooks or insert-in-front-hooks. */
2254 report_interval_modification (make_number (charpos
),
2255 make_number (charpos
+ lenins
));
2257 unbind_to (count
, Qnil
);
2261 Fcombine_after_change_execute_1 (Lisp_Object val
)
2263 Vcombine_after_change_calls
= val
;
2267 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2268 Scombine_after_change_execute
, 0, 0, 0,
2269 doc
: /* This function is for use internally in `combine-after-change-calls'. */)
2272 int count
= SPECPDL_INDEX ();
2273 EMACS_INT beg
, end
, change
;
2274 EMACS_INT begpos
, endpos
;
2277 if (NILP (combine_after_change_list
))
2280 /* It is rare for combine_after_change_buffer to be invalid, but
2281 possible. It can happen when combine-after-change-calls is
2282 non-nil, and insertion calls a file handler (e.g. through
2283 lock_file) which scribbles into a temp file -- cyd */
2284 if (!BUFFERP (combine_after_change_buffer
)
2285 || NILP (XBUFFER (combine_after_change_buffer
)->name
))
2287 combine_after_change_list
= Qnil
;
2291 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2293 Fset_buffer (combine_after_change_buffer
);
2295 /* # chars unchanged at beginning of buffer. */
2297 /* # chars unchanged at end of buffer. */
2299 /* Total amount of insertion (negative for deletion). */
2302 /* Scan the various individual changes,
2303 accumulating the range info in BEG, END and CHANGE. */
2304 for (tail
= combine_after_change_list
; CONSP (tail
);
2308 EMACS_INT thisbeg
, thisend
, thischange
;
2310 /* Extract the info from the next element. */
2314 thisbeg
= XINT (XCAR (elt
));
2319 thisend
= XINT (XCAR (elt
));
2324 thischange
= XINT (XCAR (elt
));
2326 /* Merge this range into the accumulated range. */
2327 change
+= thischange
;
2334 /* Get the current start and end positions of the range
2335 that was changed. */
2339 /* We are about to handle these, so discard them. */
2340 combine_after_change_list
= Qnil
;
2342 /* Now run the after-change functions for real.
2343 Turn off the flag that defers them. */
2344 record_unwind_protect (Fcombine_after_change_execute_1
,
2345 Vcombine_after_change_calls
);
2346 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2347 update_compositions (begpos
, endpos
, CHECK_ALL
);
2349 return unbind_to (count
, Qnil
);
2353 syms_of_insdel (void)
2355 staticpro (&combine_after_change_list
);
2356 staticpro (&combine_after_change_buffer
);
2357 combine_after_change_list
= Qnil
;
2358 combine_after_change_buffer
= Qnil
;
2360 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag
,
2361 doc
: /* Non-nil means enable debugging checks for invalid marker positions. */);
2362 check_markers_debug_flag
= 0;
2363 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls
,
2364 doc
: /* Used internally by the `combine-after-change-calls' macro. */);
2365 Vcombine_after_change_calls
= Qnil
;
2367 DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks
,
2368 doc
: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2369 This affects `before-change-functions' and `after-change-functions',
2370 as well as hooks attached to text properties and overlays. */);
2371 inhibit_modification_hooks
= 0;
2372 Qinhibit_modification_hooks
= intern_c_string ("inhibit-modification-hooks");
2373 staticpro (&Qinhibit_modification_hooks
);
2375 defsubr (&Scombine_after_change_execute
);
2378 /* arch-tag: 9b34b886-47d7-465e-a234-299af411b23d
2379 (do not change this comment) */