1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985-1986, 1993-1995, 1997-2013 Free Software
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
26 #include "intervals.h"
27 #include "character.h"
30 #include "blockinput.h"
31 #include "region-cache.h"
33 static void insert_from_string_1 (Lisp_Object
, ptrdiff_t, ptrdiff_t, ptrdiff_t,
34 ptrdiff_t, bool, bool);
35 static void insert_from_buffer_1 (struct buffer
*, ptrdiff_t, ptrdiff_t, bool);
36 static void gap_left (ptrdiff_t, ptrdiff_t, bool);
37 static void gap_right (ptrdiff_t, ptrdiff_t);
39 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
40 describing changes which happened while combine_after_change_calls
41 was non-nil. We use this to decide how to call them
42 once the deferral ends.
45 BEG-UNCHANGED is the number of chars before the changed range.
46 END-UNCHANGED is the number of chars after the changed range,
47 and CHANGE-AMOUNT is the number of characters inserted by the change
48 (negative for a deletion). */
49 static Lisp_Object combine_after_change_list
;
51 /* Buffer which combine_after_change_list is about. */
52 static Lisp_Object combine_after_change_buffer
;
54 Lisp_Object Qinhibit_modification_hooks
;
56 static void signal_before_change (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
58 /* Also used in marker.c to enable expensive marker checks. */
65 struct Lisp_Marker
*tail
;
66 bool multibyte
= ! NILP (BVAR (current_buffer
, enable_multibyte_characters
));
68 for (tail
= BUF_MARKERS (current_buffer
); tail
; tail
= tail
->next
)
70 if (tail
->buffer
->text
!= current_buffer
->text
)
72 if (tail
->charpos
> Z
)
74 if (tail
->bytepos
> Z_BYTE
)
76 if (multibyte
&& ! CHAR_HEAD_P (FETCH_BYTE (tail
->bytepos
)))
81 #else /* not MARKER_DEBUG */
83 #define check_markers() do { } while (0)
85 #endif /* MARKER_DEBUG */
87 /* Move gap to position CHARPOS.
88 Note that this can quit! */
91 move_gap (ptrdiff_t charpos
)
93 move_gap_both (charpos
, CHAR_TO_BYTE (charpos
));
96 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
97 Note that this can quit! */
100 move_gap_both (ptrdiff_t charpos
, ptrdiff_t bytepos
)
102 if (bytepos
< GPT_BYTE
)
103 gap_left (charpos
, bytepos
, 0);
104 else if (bytepos
> GPT_BYTE
)
105 gap_right (charpos
, bytepos
);
108 /* Move the gap to a position less than the current GPT.
109 BYTEPOS describes the new position as a byte position,
110 and CHARPOS is the corresponding char position.
111 If NEWGAP, then don't update beg_unchanged and end_unchanged. */
114 gap_left (ptrdiff_t charpos
, ptrdiff_t bytepos
, bool newgap
)
116 unsigned char *to
, *from
;
121 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
128 /* Now copy the characters. To move the gap down,
129 copy characters up. */
133 /* I gets number of characters left to copy. */
134 i
= new_s1
- bytepos
;
137 /* If a quit is requested, stop copying now.
138 Change BYTEPOS to be where we have actually moved the gap to. */
142 charpos
= BYTE_TO_CHAR (bytepos
);
145 /* Move at most 32000 chars before checking again for a quit. */
150 memmove (to
, from
, i
);
153 /* Adjust buffer data structure, to put the gap at BYTEPOS.
154 BYTEPOS is where the loop above stopped, which may be what
155 was specified or may be where a quit was detected. */
158 eassert (charpos
<= bytepos
);
159 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
163 /* Move the gap to a position greater than the current GPT.
164 BYTEPOS describes the new position as a byte position,
165 and CHARPOS is the corresponding char position. */
168 gap_right (ptrdiff_t charpos
, ptrdiff_t bytepos
)
170 register unsigned char *to
, *from
;
171 register ptrdiff_t i
;
174 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
181 /* Now copy the characters. To move the gap up,
182 copy characters down. */
186 /* I gets number of characters left to copy. */
187 i
= bytepos
- new_s1
;
190 /* If a quit is requested, stop copying now.
191 Change BYTEPOS to be where we have actually moved the gap to. */
195 charpos
= BYTE_TO_CHAR (bytepos
);
198 /* Move at most 32000 chars before checking again for a quit. */
202 memmove (to
, from
, i
);
208 eassert (charpos
<= bytepos
);
209 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
213 /* Adjust all markers for a deletion
214 whose range in bytes is FROM_BYTE to TO_BYTE.
215 The range in charpos is FROM to TO.
217 This function assumes that the gap is adjacent to
218 or inside of the range being deleted. */
221 adjust_markers_for_delete (ptrdiff_t from
, ptrdiff_t from_byte
,
222 ptrdiff_t to
, ptrdiff_t to_byte
)
225 register struct Lisp_Marker
*m
;
226 register ptrdiff_t charpos
;
228 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
230 charpos
= m
->charpos
;
231 eassert (charpos
<= Z
);
233 /* If the marker is after the deletion,
234 relocate by number of chars / bytes deleted. */
237 m
->charpos
-= to
- from
;
238 m
->bytepos
-= to_byte
- from_byte
;
240 /* Here's the case where a marker is inside text being deleted. */
241 else if (charpos
> from
)
243 if (! m
->insertion_type
)
244 { /* Normal markers will end up at the beginning of the
245 re-inserted text after undoing a deletion, and must be
246 adjusted to move them to the correct place. */
247 XSETMISC (marker
, m
);
248 record_marker_adjustment (marker
, from
- charpos
);
250 else if (charpos
< to
)
251 { /* Before-insertion markers will automatically move forward
252 upon re-inserting the deleted text, so we have to arrange
253 for them to move backward to the correct position. */
254 XSETMISC (marker
, m
);
255 record_marker_adjustment (marker
, to
- charpos
);
258 m
->bytepos
= from_byte
;
260 /* Here's the case where a before-insertion marker is immediately
261 before the deleted region. */
262 else if (charpos
== from
&& m
->insertion_type
)
264 /* Undoing the change uses normal insertion, which will
265 incorrectly make MARKER move forward, so we arrange for it
266 to then move backward to the correct place at the beginning
267 of the deleted region. */
268 XSETMISC (marker
, m
);
269 record_marker_adjustment (marker
, to
- from
);
275 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
276 to TO / TO_BYTE. We have to relocate the charpos of every marker
277 that points after the insertion (but not their bytepos).
279 When a marker points at the insertion point,
280 we advance it if either its insertion-type is t
281 or BEFORE_MARKERS is true. */
284 adjust_markers_for_insert (ptrdiff_t from
, ptrdiff_t from_byte
,
285 ptrdiff_t to
, ptrdiff_t to_byte
, bool before_markers
)
287 struct Lisp_Marker
*m
;
289 ptrdiff_t nchars
= to
- from
;
290 ptrdiff_t nbytes
= to_byte
- from_byte
;
292 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
294 eassert (m
->bytepos
>= m
->charpos
295 && m
->bytepos
- m
->charpos
<= Z_BYTE
- Z
);
297 if (m
->bytepos
== from_byte
)
299 if (m
->insertion_type
|| before_markers
)
301 m
->bytepos
= to_byte
;
303 if (m
->insertion_type
)
307 else if (m
->bytepos
> from_byte
)
309 m
->bytepos
+= nbytes
;
310 m
->charpos
+= nchars
;
314 /* Adjusting only markers whose insertion-type is t may result in
315 - disordered start and end in overlays, and
316 - disordered overlays in the slot `overlays_before' of current_buffer. */
319 fix_start_end_in_overlays (from
, to
);
320 fix_overlays_before (current_buffer
, from
, to
);
324 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
326 This is used only when the value of point changes due to an insert
327 or delete; it does not represent a conceptual change in point as a
328 marker. In particular, point is not crossing any interval
329 boundaries, so there's no need to use the usual SET_PT macro. In
330 fact it would be incorrect to do so, because either the old or the
331 new value of point is out of sync with the current set of
335 adjust_point (ptrdiff_t nchars
, ptrdiff_t nbytes
)
337 SET_BUF_PT_BOTH (current_buffer
, PT
+ nchars
, PT_BYTE
+ nbytes
);
338 /* In a single-byte buffer, the two positions must be equal. */
339 eassert (PT_BYTE
>= PT
&& PT_BYTE
- PT
<= ZV_BYTE
- ZV
);
342 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
343 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
344 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
348 adjust_markers_for_replace (ptrdiff_t from
, ptrdiff_t from_byte
,
349 ptrdiff_t old_chars
, ptrdiff_t old_bytes
,
350 ptrdiff_t new_chars
, ptrdiff_t new_bytes
)
352 register struct Lisp_Marker
*m
;
353 ptrdiff_t prev_to_byte
= from_byte
+ old_bytes
;
354 ptrdiff_t diff_chars
= new_chars
- old_chars
;
355 ptrdiff_t diff_bytes
= new_bytes
- old_bytes
;
357 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
359 if (m
->bytepos
>= prev_to_byte
)
361 m
->charpos
+= diff_chars
;
362 m
->bytepos
+= diff_bytes
;
364 else if (m
->bytepos
> from_byte
)
367 m
->bytepos
= from_byte
;
376 buffer_overflow (void)
378 error ("Maximum buffer size exceeded");
381 /* Make the gap NBYTES_ADDED bytes longer. */
384 make_gap_larger (ptrdiff_t nbytes_added
)
387 ptrdiff_t real_gap_loc
;
388 ptrdiff_t real_gap_loc_byte
;
389 ptrdiff_t old_gap_size
;
390 ptrdiff_t current_size
= Z_BYTE
- BEG_BYTE
+ GAP_SIZE
;
392 if (BUF_BYTES_MAX
- current_size
< nbytes_added
)
395 /* If we have to get more space, get enough to last a while;
396 but do not exceed the maximum buffer size. */
397 nbytes_added
= min (nbytes_added
+ GAP_BYTES_DFL
,
398 BUF_BYTES_MAX
- current_size
);
400 enlarge_buffer_text (current_buffer
, nbytes_added
);
402 /* Prevent quitting in move_gap. */
407 real_gap_loc_byte
= GPT_BYTE
;
408 old_gap_size
= GAP_SIZE
;
410 /* Call the newly allocated space a gap at the end of the whole space. */
412 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
413 GAP_SIZE
= nbytes_added
;
415 /* Move the new gap down to be consecutive with the end of the old one.
416 This adjusts the markers properly too. */
417 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
419 /* Now combine the two into one large gap. */
420 GAP_SIZE
+= old_gap_size
;
422 GPT_BYTE
= real_gap_loc_byte
;
430 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
432 /* Make the gap NBYTES_REMOVED bytes shorter. */
435 make_gap_smaller (ptrdiff_t nbytes_removed
)
438 ptrdiff_t real_gap_loc
;
439 ptrdiff_t real_gap_loc_byte
;
441 ptrdiff_t real_Z_byte
;
442 ptrdiff_t real_beg_unchanged
;
443 ptrdiff_t new_gap_size
;
445 /* Make sure the gap is at least GAP_BYTES_MIN bytes. */
446 if (GAP_SIZE
- nbytes_removed
< GAP_BYTES_MIN
)
447 nbytes_removed
= GAP_SIZE
- GAP_BYTES_MIN
;
449 /* Prevent quitting in move_gap. */
454 real_gap_loc_byte
= GPT_BYTE
;
455 new_gap_size
= GAP_SIZE
- nbytes_removed
;
457 real_Z_byte
= Z_BYTE
;
458 real_beg_unchanged
= BEG_UNCHANGED
;
460 /* Pretend that the last unwanted part of the gap is the entire gap,
461 and that the first desired part of the gap is part of the buffer
463 memset (GPT_ADDR
, 0, new_gap_size
);
465 GPT_BYTE
+= new_gap_size
;
467 Z_BYTE
+= new_gap_size
;
468 GAP_SIZE
= nbytes_removed
;
470 /* Move the unwanted pretend gap to the end of the buffer. This
471 adjusts the markers properly too. */
472 gap_right (Z
, Z_BYTE
);
474 enlarge_buffer_text (current_buffer
, -nbytes_removed
);
476 /* Now restore the desired gap. */
477 GAP_SIZE
= new_gap_size
;
479 GPT_BYTE
= real_gap_loc_byte
;
481 Z_BYTE
= real_Z_byte
;
482 BEG_UNCHANGED
= real_beg_unchanged
;
490 #endif /* USE_MMAP_FOR_BUFFERS || REL_ALLOC || DOUG_LEA_MALLOC */
493 make_gap (ptrdiff_t nbytes_added
)
495 if (nbytes_added
>= 0)
496 make_gap_larger (nbytes_added
);
497 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
499 make_gap_smaller (-nbytes_added
);
503 /* Add NBYTES to B's gap. It's enough to temporarily
504 fake current_buffer and avoid real switch to B. */
507 make_gap_1 (struct buffer
*b
, ptrdiff_t nbytes
)
509 struct buffer
*oldb
= current_buffer
;
513 current_buffer
= oldb
;
516 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
517 FROM_MULTIBYTE says whether the incoming text is multibyte.
518 TO_MULTIBYTE says whether to store the text as multibyte.
519 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
521 Return the number of bytes stored at TO_ADDR. */
524 copy_text (const unsigned char *from_addr
, unsigned char *to_addr
,
525 ptrdiff_t nbytes
, bool from_multibyte
, bool to_multibyte
)
527 if (from_multibyte
== to_multibyte
)
529 memcpy (to_addr
, from_addr
, nbytes
);
532 else if (from_multibyte
)
534 ptrdiff_t nchars
= 0;
535 ptrdiff_t bytes_left
= nbytes
;
537 while (bytes_left
> 0)
540 c
= STRING_CHAR_AND_LENGTH (from_addr
, thislen
);
541 if (! ASCII_CHAR_P (c
))
544 from_addr
+= thislen
;
545 bytes_left
-= thislen
;
552 unsigned char *initial_to_addr
= to_addr
;
554 /* Convert single-byte to multibyte. */
557 int c
= *from_addr
++;
559 if (!ASCII_CHAR_P (c
))
561 c
= BYTE8_TO_CHAR (c
);
562 to_addr
+= CHAR_STRING (c
, to_addr
);
566 /* Special case for speed. */
567 *to_addr
++ = c
, nbytes
--;
569 return to_addr
- initial_to_addr
;
573 /* Insert a string of specified length before point.
574 This function judges multibyteness based on
575 enable_multibyte_characters in the current buffer;
576 it never converts between single-byte and multibyte.
578 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
579 prepare_to_modify_buffer could relocate the text. */
582 insert (const char *string
, ptrdiff_t nbytes
)
586 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
587 insert_1_both (string
, len
, nbytes
, 0, 1, 0);
589 signal_after_change (opoint
, 0, len
);
590 update_compositions (opoint
, PT
, CHECK_BORDER
);
594 /* Likewise, but inherit text properties from neighboring characters. */
597 insert_and_inherit (const char *string
, ptrdiff_t nbytes
)
601 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
602 insert_1_both (string
, len
, nbytes
, 1, 1, 0);
604 signal_after_change (opoint
, 0, len
);
605 update_compositions (opoint
, PT
, CHECK_BORDER
);
609 /* Insert the character C before point. Do not inherit text properties. */
614 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
617 if (! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
618 len
= CHAR_STRING (c
, str
);
625 insert ((char *) str
, len
);
628 /* Insert the null-terminated string S before point. */
631 insert_string (const char *s
)
633 insert (s
, strlen (s
));
636 /* Like `insert' except that all markers pointing at the place where
637 the insertion happens are adjusted to point after it.
638 Don't use this function to insert part of a Lisp string,
639 since gc could happen and relocate it. */
642 insert_before_markers (const char *string
, ptrdiff_t nbytes
)
646 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
647 insert_1_both (string
, len
, nbytes
, 0, 1, 1);
649 signal_after_change (opoint
, 0, len
);
650 update_compositions (opoint
, PT
, CHECK_BORDER
);
654 /* Likewise, but inherit text properties from neighboring characters. */
657 insert_before_markers_and_inherit (const char *string
,
662 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
663 insert_1_both (string
, len
, nbytes
, 1, 1, 1);
665 signal_after_change (opoint
, 0, len
);
666 update_compositions (opoint
, PT
, CHECK_BORDER
);
670 /* Subroutine used by the insert functions above. */
673 insert_1 (const char *string
, ptrdiff_t nbytes
,
674 bool inherit
, bool prepare
, bool before_markers
)
676 insert_1_both (string
, chars_in_text ((unsigned char *) string
, nbytes
),
677 nbytes
, inherit
, prepare
, before_markers
);
681 #ifdef BYTE_COMBINING_DEBUG
683 /* See if the bytes before POS/POS_BYTE combine with bytes
684 at the start of STRING to form a single character.
685 If so, return the number of bytes at the start of STRING
686 which combine in this way. Otherwise, return 0. */
689 count_combining_before (const unsigned char *string
, ptrdiff_t length
,
690 ptrdiff_t pos
, ptrdiff_t pos_byte
)
692 int len
, combining_bytes
;
693 const unsigned char *p
;
695 if (NILP (current_buffer
->enable_multibyte_characters
))
698 /* At first, we can exclude the following cases:
699 (1) STRING[0] can't be a following byte of multibyte sequence.
700 (2) POS is the start of the current buffer.
701 (3) A character before POS is not a multibyte character. */
702 if (length
== 0 || CHAR_HEAD_P (*string
)) /* case (1) */
704 if (pos_byte
== BEG_BYTE
) /* case (2) */
707 p
= BYTE_POS_ADDR (pos_byte
- 1);
708 while (! CHAR_HEAD_P (*p
)) p
--, len
++;
709 if (! LEADING_CODE_P (*p
)) /* case (3) */
712 combining_bytes
= BYTES_BY_CHAR_HEAD (*p
) - len
;
713 if (combining_bytes
<= 0)
714 /* The character preceding POS is, complete and no room for
715 combining bytes (combining_bytes == 0), or an independent 8-bit
716 character (combining_bytes < 0). */
719 /* We have a combination situation. Count the bytes at STRING that
722 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
725 return (combining_bytes
< p
- string
? combining_bytes
: p
- string
);
728 /* See if the bytes after POS/POS_BYTE combine with bytes
729 at the end of STRING to form a single character.
730 If so, return the number of bytes after POS/POS_BYTE
731 which combine in this way. Otherwise, return 0. */
734 count_combining_after (const unsigned char *string
,
735 ptrdiff_t length
, ptrdiff_t pos
, ptrdiff_t pos_byte
)
737 ptrdiff_t opos_byte
= pos_byte
;
742 if (NILP (current_buffer
->enable_multibyte_characters
))
745 /* At first, we can exclude the following cases:
746 (1) The last byte of STRING is an ASCII.
747 (2) POS is the last of the current buffer.
748 (3) A character at POS can't be a following byte of multibyte
750 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1])) /* case (1) */
752 if (pos_byte
== Z_BYTE
) /* case (2) */
754 bufp
= BYTE_POS_ADDR (pos_byte
);
755 if (CHAR_HEAD_P (*bufp
)) /* case (3) */
759 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
765 /* All characters in STRING are not character head. We must
766 check also preceding bytes at POS. We are sure that the gap
768 unsigned char *p
= BEG_ADDR
;
770 while (i
>= 0 && ! CHAR_HEAD_P (p
[i
]))
772 if (i
< 0 || !LEADING_CODE_P (p
[i
]))
775 bytes
= BYTES_BY_CHAR_HEAD (p
[i
]);
776 return (bytes
<= pos_byte
- 1 - i
+ length
778 : bytes
- (pos_byte
- 1 - i
+ length
));
780 if (!LEADING_CODE_P (string
[i
]))
783 bytes
= BYTES_BY_CHAR_HEAD (string
[i
]) - (length
- i
);
785 while (!CHAR_HEAD_P (*bufp
)) bufp
++, pos_byte
++;
787 return (bytes
<= pos_byte
- opos_byte
? bytes
: pos_byte
- opos_byte
);
793 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
794 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
795 are the same as in insert_1. */
798 insert_1_both (const char *string
,
799 ptrdiff_t nchars
, ptrdiff_t nbytes
,
800 bool inherit
, bool prepare
, bool before_markers
)
805 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
809 /* Do this before moving and increasing the gap,
810 because the before-change hooks might move the gap
811 or make it smaller. */
812 prepare_to_modify_buffer (PT
, PT
, NULL
);
815 move_gap_both (PT
, PT_BYTE
);
816 if (GAP_SIZE
< nbytes
)
817 make_gap (nbytes
- GAP_SIZE
);
819 #ifdef BYTE_COMBINING_DEBUG
820 if (count_combining_before (string
, nbytes
, PT
, PT_BYTE
)
821 || count_combining_after (string
, nbytes
, PT
, PT_BYTE
))
825 /* Record deletion of the surrounding text that combines with
826 the insertion. This, together with recording the insertion,
827 will add up to the right stuff in the undo list. */
828 record_insert (PT
, nchars
);
830 CHARS_MODIFF
= MODIFF
;
832 memcpy (GPT_ADDR
, string
, nbytes
);
841 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
843 eassert (GPT
<= GPT_BYTE
);
845 /* The insert may have been in the unchanged region, so check again. */
846 if (Z
- GPT
< END_UNCHANGED
)
847 END_UNCHANGED
= Z
- GPT
;
849 adjust_overlays_for_insert (PT
, nchars
);
850 adjust_markers_for_insert (PT
, PT_BYTE
,
851 PT
+ nchars
, PT_BYTE
+ nbytes
,
854 offset_intervals (current_buffer
, PT
, nchars
);
856 if (!inherit
&& buffer_intervals (current_buffer
))
857 set_text_properties (make_number (PT
), make_number (PT
+ nchars
),
860 adjust_point (nchars
, nbytes
);
865 /* Insert the part of the text of STRING, a Lisp object assumed to be
866 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
867 starting at position POS / POS_BYTE. If the text of STRING has properties,
868 copy them into the buffer.
870 It does not work to use `insert' for this, because a GC could happen
871 before we copy the stuff into the buffer, and relocate the string
872 without insert noticing. */
875 insert_from_string (Lisp_Object string
, ptrdiff_t pos
, ptrdiff_t pos_byte
,
876 ptrdiff_t length
, ptrdiff_t length_byte
, bool inherit
)
878 ptrdiff_t opoint
= PT
;
880 if (SCHARS (string
) == 0)
883 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
885 signal_after_change (opoint
, 0, PT
- opoint
);
886 update_compositions (opoint
, PT
, CHECK_BORDER
);
889 /* Like `insert_from_string' except that all markers pointing
890 at the place where the insertion happens are adjusted to point after it. */
893 insert_from_string_before_markers (Lisp_Object string
,
894 ptrdiff_t pos
, ptrdiff_t pos_byte
,
895 ptrdiff_t length
, ptrdiff_t length_byte
,
898 ptrdiff_t opoint
= PT
;
900 if (SCHARS (string
) == 0)
903 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
905 signal_after_change (opoint
, 0, PT
- opoint
);
906 update_compositions (opoint
, PT
, CHECK_BORDER
);
909 /* Subroutine of the insertion functions above. */
912 insert_from_string_1 (Lisp_Object string
, ptrdiff_t pos
, ptrdiff_t pos_byte
,
913 ptrdiff_t nchars
, ptrdiff_t nbytes
,
914 bool inherit
, bool before_markers
)
917 ptrdiff_t outgoing_nbytes
= nbytes
;
920 /* Make OUTGOING_NBYTES describe the text
921 as it will be inserted in this buffer. */
923 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
924 outgoing_nbytes
= nchars
;
925 else if (! STRING_MULTIBYTE (string
))
927 = count_size_as_multibyte (SDATA (string
) + pos_byte
,
931 /* Do this before moving and increasing the gap,
932 because the before-change hooks might move the gap
933 or make it smaller. */
934 prepare_to_modify_buffer (PT
, PT
, NULL
);
937 move_gap_both (PT
, PT_BYTE
);
938 if (GAP_SIZE
< outgoing_nbytes
)
939 make_gap (outgoing_nbytes
- GAP_SIZE
);
942 /* Copy the string text into the buffer, perhaps converting
943 between single-byte and multibyte. */
944 copy_text (SDATA (string
) + pos_byte
, GPT_ADDR
, nbytes
,
945 STRING_MULTIBYTE (string
),
946 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
948 #ifdef BYTE_COMBINING_DEBUG
949 /* We have copied text into the gap, but we have not altered
950 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
951 to these functions and get the same results as we would
952 have got earlier on. Meanwhile, PT_ADDR does point to
953 the text that has been stored by copy_text. */
954 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
955 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
959 record_insert (PT
, nchars
);
961 CHARS_MODIFF
= MODIFF
;
963 GAP_SIZE
-= outgoing_nbytes
;
967 GPT_BYTE
+= outgoing_nbytes
;
968 ZV_BYTE
+= outgoing_nbytes
;
969 Z_BYTE
+= outgoing_nbytes
;
970 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
972 eassert (GPT
<= GPT_BYTE
);
974 /* The insert may have been in the unchanged region, so check again. */
975 if (Z
- GPT
< END_UNCHANGED
)
976 END_UNCHANGED
= Z
- GPT
;
978 adjust_overlays_for_insert (PT
, nchars
);
979 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
980 PT_BYTE
+ outgoing_nbytes
,
983 offset_intervals (current_buffer
, PT
, nchars
);
985 intervals
= string_intervals (string
);
986 /* Get the intervals for the part of the string we are inserting. */
987 if (nbytes
< SBYTES (string
))
988 intervals
= copy_intervals (intervals
, pos
, nchars
);
990 /* Insert those intervals. */
991 graft_intervals_into_buffer (intervals
, PT
, nchars
,
992 current_buffer
, inherit
);
994 adjust_point (nchars
, outgoing_nbytes
);
999 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1000 starting at GPT_ADDR. */
1003 insert_from_gap (ptrdiff_t nchars
, ptrdiff_t nbytes
)
1005 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1008 record_insert (GPT
, nchars
);
1018 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1020 eassert (GPT
<= GPT_BYTE
);
1022 adjust_overlays_for_insert (GPT
- nchars
, nchars
);
1023 adjust_markers_for_insert (GPT
- nchars
, GPT_BYTE
- nbytes
,
1026 if (buffer_intervals (current_buffer
))
1028 offset_intervals (current_buffer
, GPT
- nchars
, nchars
);
1029 graft_intervals_into_buffer (NULL
, GPT
- nchars
, nchars
,
1033 if (GPT
- nchars
< PT
)
1034 adjust_point (nchars
, nbytes
);
1039 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1040 current buffer. If the text in BUF has properties, they are absorbed
1041 into the current buffer.
1043 It does not work to use `insert' for this, because a malloc could happen
1044 and relocate BUF's text before the copy happens. */
1047 insert_from_buffer (struct buffer
*buf
,
1048 ptrdiff_t charpos
, ptrdiff_t nchars
, bool inherit
)
1050 ptrdiff_t opoint
= PT
;
1052 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1053 signal_after_change (opoint
, 0, PT
- opoint
);
1054 update_compositions (opoint
, PT
, CHECK_BORDER
);
1058 insert_from_buffer_1 (struct buffer
*buf
,
1059 ptrdiff_t from
, ptrdiff_t nchars
, bool inherit
)
1061 ptrdiff_t chunk
, chunk_expanded
;
1062 ptrdiff_t from_byte
= buf_charpos_to_bytepos (buf
, from
);
1063 ptrdiff_t to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1064 ptrdiff_t incoming_nbytes
= to_byte
- from_byte
;
1065 ptrdiff_t outgoing_nbytes
= incoming_nbytes
;
1068 /* Make OUTGOING_NBYTES describe the text
1069 as it will be inserted in this buffer. */
1071 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1072 outgoing_nbytes
= nchars
;
1073 else if (NILP (BVAR (buf
, enable_multibyte_characters
)))
1075 ptrdiff_t outgoing_before_gap
= 0;
1076 ptrdiff_t outgoing_after_gap
= 0;
1078 if (from
< BUF_GPT (buf
))
1080 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1081 if (chunk
> incoming_nbytes
)
1082 chunk
= incoming_nbytes
;
1084 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1090 if (chunk
< incoming_nbytes
)
1092 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
,
1094 incoming_nbytes
- chunk
);
1096 outgoing_nbytes
= outgoing_before_gap
+ outgoing_after_gap
;
1099 /* Do this before moving and increasing the gap,
1100 because the before-change hooks might move the gap
1101 or make it smaller. */
1102 prepare_to_modify_buffer (PT
, PT
, NULL
);
1105 move_gap_both (PT
, PT_BYTE
);
1106 if (GAP_SIZE
< outgoing_nbytes
)
1107 make_gap (outgoing_nbytes
- GAP_SIZE
);
1109 if (from
< BUF_GPT (buf
))
1111 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1112 if (chunk
> incoming_nbytes
)
1113 chunk
= incoming_nbytes
;
1114 /* Record number of output bytes, so we know where
1115 to put the output from the second copy_text. */
1117 = copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1119 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1120 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1123 chunk_expanded
= chunk
= 0;
1125 if (chunk
< incoming_nbytes
)
1126 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1127 GPT_ADDR
+ chunk_expanded
, incoming_nbytes
- chunk
,
1128 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1129 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1131 #ifdef BYTE_COMBINING_DEBUG
1132 /* We have copied text into the gap, but we have not altered
1133 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1134 to these functions and get the same results as we would
1135 have got earlier on. Meanwhile, GPT_ADDR does point to
1136 the text that has been stored by copy_text. */
1137 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1138 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1142 record_insert (PT
, nchars
);
1144 CHARS_MODIFF
= MODIFF
;
1146 GAP_SIZE
-= outgoing_nbytes
;
1150 GPT_BYTE
+= outgoing_nbytes
;
1151 ZV_BYTE
+= outgoing_nbytes
;
1152 Z_BYTE
+= outgoing_nbytes
;
1153 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1155 eassert (GPT
<= GPT_BYTE
);
1157 /* The insert may have been in the unchanged region, so check again. */
1158 if (Z
- GPT
< END_UNCHANGED
)
1159 END_UNCHANGED
= Z
- GPT
;
1161 adjust_overlays_for_insert (PT
, nchars
);
1162 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1163 PT_BYTE
+ outgoing_nbytes
,
1166 offset_intervals (current_buffer
, PT
, nchars
);
1168 /* Get the intervals for the part of the string we are inserting. */
1169 intervals
= buffer_intervals (buf
);
1170 if (nchars
< BUF_Z (buf
) - BUF_BEG (buf
))
1172 if (buf
== current_buffer
&& PT
<= from
)
1174 intervals
= copy_intervals (intervals
, from
, nchars
);
1177 /* Insert those intervals. */
1178 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1180 adjust_point (nchars
, outgoing_nbytes
);
1183 /* Record undo information and adjust markers and position keepers for
1184 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1185 chars (LEN_BYTE bytes) which resides in the gap just after
1188 PREV_TEXT nil means the new text was just inserted. */
1191 adjust_after_replace (ptrdiff_t from
, ptrdiff_t from_byte
,
1192 Lisp_Object prev_text
, ptrdiff_t len
, ptrdiff_t len_byte
)
1194 ptrdiff_t nchars_del
= 0, nbytes_del
= 0;
1196 #ifdef BYTE_COMBINING_DEBUG
1197 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1198 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1202 if (STRINGP (prev_text
))
1204 nchars_del
= SCHARS (prev_text
);
1205 nbytes_del
= SBYTES (prev_text
);
1208 /* Update various buffer positions for the new text. */
1209 GAP_SIZE
-= len_byte
;
1211 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1212 GPT
+= len
; GPT_BYTE
+= len_byte
;
1213 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1216 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1219 adjust_markers_for_insert (from
, from_byte
,
1220 from
+ len
, from_byte
+ len_byte
, 0);
1222 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1225 record_delete (from
, prev_text
);
1226 record_insert (from
, len
);
1229 if (len
> nchars_del
)
1230 adjust_overlays_for_insert (from
, len
- nchars_del
);
1231 else if (len
< nchars_del
)
1232 adjust_overlays_for_delete (from
, nchars_del
- len
);
1234 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1237 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1239 /* As byte combining will decrease Z, we must check this again. */
1240 if (Z
- GPT
< END_UNCHANGED
)
1241 END_UNCHANGED
= Z
- GPT
;
1246 evaporate_overlays (from
);
1248 CHARS_MODIFF
= MODIFF
;
1251 /* Record undo information, adjust markers and position keepers for an
1252 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1253 text already exists in the current buffer but character length (TO
1254 - FROM) may be incorrect, the correct length is NEWLEN. */
1257 adjust_after_insert (ptrdiff_t from
, ptrdiff_t from_byte
,
1258 ptrdiff_t to
, ptrdiff_t to_byte
, ptrdiff_t newlen
)
1260 ptrdiff_t len
= to
- from
, len_byte
= to_byte
- from_byte
;
1263 move_gap_both (to
, to_byte
);
1264 GAP_SIZE
+= len_byte
;
1265 GPT
-= len
; GPT_BYTE
-= len_byte
;
1266 ZV
-= len
; ZV_BYTE
-= len_byte
;
1267 Z
-= len
; Z_BYTE
-= len_byte
;
1268 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1271 /* Replace the text from character positions FROM to TO with NEW,
1272 If PREPARE, call prepare_to_modify_buffer.
1273 If INHERIT, the newly inserted text should inherit text properties
1274 from the surrounding non-deleted text. */
1276 /* Note that this does not yet handle markers quite right.
1277 Also it needs to record a single undo-entry that does a replacement
1278 rather than a separate delete and insert.
1279 That way, undo will also handle markers properly.
1281 But if MARKERS is 0, don't relocate markers. */
1284 replace_range (ptrdiff_t from
, ptrdiff_t to
, Lisp_Object
new,
1285 bool prepare
, bool inherit
, bool markers
)
1287 ptrdiff_t inschars
= SCHARS (new);
1288 ptrdiff_t insbytes
= SBYTES (new);
1289 ptrdiff_t from_byte
, to_byte
;
1290 ptrdiff_t nbytes_del
, nchars_del
;
1291 struct gcpro gcpro1
;
1293 ptrdiff_t outgoing_insbytes
= insbytes
;
1294 Lisp_Object deletion
;
1303 ptrdiff_t range_length
= to
- from
;
1304 prepare_to_modify_buffer (from
, to
, &from
);
1305 to
= from
+ range_length
;
1310 /* Make args be valid. */
1316 from_byte
= CHAR_TO_BYTE (from
);
1317 to_byte
= CHAR_TO_BYTE (to
);
1319 nchars_del
= to
- from
;
1320 nbytes_del
= to_byte
- from_byte
;
1322 if (nbytes_del
<= 0 && insbytes
== 0)
1325 /* Make OUTGOING_INSBYTES describe the text
1326 as it will be inserted in this buffer. */
1328 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1329 outgoing_insbytes
= inschars
;
1330 else if (! STRING_MULTIBYTE (new))
1332 = count_size_as_multibyte (SDATA (new), insbytes
);
1336 /* Make sure the gap is somewhere in or next to what we are deleting. */
1338 gap_right (from
, from_byte
);
1340 gap_left (to
, to_byte
, 0);
1342 /* Even if we don't record for undo, we must keep the original text
1343 because we may have to recover it because of inappropriate byte
1345 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1346 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1348 GAP_SIZE
+= nbytes_del
;
1351 ZV_BYTE
-= nbytes_del
;
1352 Z_BYTE
-= nbytes_del
;
1354 GPT_BYTE
= from_byte
;
1355 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1357 eassert (GPT
<= GPT_BYTE
);
1359 if (GPT
- BEG
< BEG_UNCHANGED
)
1360 BEG_UNCHANGED
= GPT
- BEG
;
1361 if (Z
- GPT
< END_UNCHANGED
)
1362 END_UNCHANGED
= Z
- GPT
;
1364 if (GAP_SIZE
< outgoing_insbytes
)
1365 make_gap (outgoing_insbytes
- GAP_SIZE
);
1367 /* Copy the string text into the buffer, perhaps converting
1368 between single-byte and multibyte. */
1369 copy_text (SDATA (new), GPT_ADDR
, insbytes
,
1370 STRING_MULTIBYTE (new),
1371 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1373 #ifdef BYTE_COMBINING_DEBUG
1374 /* We have copied text into the gap, but we have not marked
1375 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1376 here, for both the previous text and the following text.
1377 Meanwhile, GPT_ADDR does point to
1378 the text that has been stored by copy_text. */
1379 if (count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
)
1380 || count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
))
1384 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1386 /* Record the insertion first, so that when we undo,
1387 the deletion will be undone first. Thus, undo
1388 will insert before deleting, and thus will keep
1389 the markers before and after this text separate. */
1390 record_insert (from
+ SCHARS (deletion
), inschars
);
1391 record_delete (from
, deletion
);
1394 GAP_SIZE
-= outgoing_insbytes
;
1398 GPT_BYTE
+= outgoing_insbytes
;
1399 ZV_BYTE
+= outgoing_insbytes
;
1400 Z_BYTE
+= outgoing_insbytes
;
1401 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1403 eassert (GPT
<= GPT_BYTE
);
1405 /* Adjust markers for the deletion and the insertion. */
1407 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1408 inschars
, outgoing_insbytes
);
1410 /* Adjust the overlay center as needed. This must be done after
1411 adjusting the markers that bound the overlays. */
1412 adjust_overlays_for_delete (from
, nchars_del
);
1413 adjust_overlays_for_insert (from
, inschars
);
1415 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1417 /* Get the intervals for the part of the string we are inserting--
1418 not including the combined-before bytes. */
1419 intervals
= string_intervals (new);
1420 /* Insert those intervals. */
1421 graft_intervals_into_buffer (intervals
, from
, inschars
,
1422 current_buffer
, inherit
);
1424 /* Relocate point as if it were a marker. */
1426 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1427 (from_byte
+ outgoing_insbytes
1428 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1430 if (outgoing_insbytes
== 0)
1431 evaporate_overlays (from
);
1436 CHARS_MODIFF
= MODIFF
;
1439 signal_after_change (from
, nchars_del
, GPT
- from
);
1440 update_compositions (from
, GPT
, CHECK_BORDER
);
1443 /* Replace the text from character positions FROM to TO with
1444 the text in INS of length INSCHARS.
1445 Keep the text properties that applied to the old characters
1446 (extending them to all the new chars if there are more new chars).
1448 Note that this does not yet handle markers quite right.
1450 If MARKERS, relocate markers.
1452 Unlike most functions at this level, never call
1453 prepare_to_modify_buffer and never call signal_after_change. */
1456 replace_range_2 (ptrdiff_t from
, ptrdiff_t from_byte
,
1457 ptrdiff_t to
, ptrdiff_t to_byte
,
1458 const char *ins
, ptrdiff_t inschars
, ptrdiff_t insbytes
,
1461 ptrdiff_t nbytes_del
, nchars_del
;
1465 nchars_del
= to
- from
;
1466 nbytes_del
= to_byte
- from_byte
;
1468 if (nbytes_del
<= 0 && insbytes
== 0)
1471 /* Make sure the gap is somewhere in or next to what we are deleting. */
1473 gap_right (from
, from_byte
);
1475 gap_left (to
, to_byte
, 0);
1477 GAP_SIZE
+= nbytes_del
;
1480 ZV_BYTE
-= nbytes_del
;
1481 Z_BYTE
-= nbytes_del
;
1483 GPT_BYTE
= from_byte
;
1484 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1486 eassert (GPT
<= GPT_BYTE
);
1488 if (GPT
- BEG
< BEG_UNCHANGED
)
1489 BEG_UNCHANGED
= GPT
- BEG
;
1490 if (Z
- GPT
< END_UNCHANGED
)
1491 END_UNCHANGED
= Z
- GPT
;
1493 if (GAP_SIZE
< insbytes
)
1494 make_gap (insbytes
- GAP_SIZE
);
1496 /* Copy the replacement text into the buffer. */
1497 memcpy (GPT_ADDR
, ins
, insbytes
);
1499 #ifdef BYTE_COMBINING_DEBUG
1500 /* We have copied text into the gap, but we have not marked
1501 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1502 here, for both the previous text and the following text.
1503 Meanwhile, GPT_ADDR does point to
1504 the text that has been stored by copy_text. */
1505 if (count_combining_before (GPT_ADDR
, insbytes
, from
, from_byte
)
1506 || count_combining_after (GPT_ADDR
, insbytes
, from
, from_byte
))
1510 GAP_SIZE
-= insbytes
;
1514 GPT_BYTE
+= insbytes
;
1515 ZV_BYTE
+= insbytes
;
1517 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1519 eassert (GPT
<= GPT_BYTE
);
1521 /* Adjust markers for the deletion and the insertion. */
1523 && ! (nchars_del
== 1 && inschars
== 1 && nbytes_del
== insbytes
))
1524 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1525 inschars
, insbytes
);
1527 /* Adjust the overlay center as needed. This must be done after
1528 adjusting the markers that bound the overlays. */
1529 if (nchars_del
!= inschars
)
1531 adjust_overlays_for_insert (from
, inschars
);
1532 adjust_overlays_for_delete (from
+ inschars
, nchars_del
);
1535 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1537 /* Relocate point as if it were a marker. */
1538 if (from
< PT
&& (nchars_del
!= inschars
|| nbytes_del
!= insbytes
))
1541 /* PT was within the deleted text. Move it to FROM. */
1542 adjust_point (from
- PT
, from_byte
- PT_BYTE
);
1544 adjust_point (inschars
- nchars_del
, insbytes
- nbytes_del
);
1548 evaporate_overlays (from
);
1553 CHARS_MODIFF
= MODIFF
;
1556 /* Delete characters in current buffer
1557 from FROM up to (but not including) TO.
1558 If TO comes before FROM, we delete nothing. */
1561 del_range (ptrdiff_t from
, ptrdiff_t to
)
1563 del_range_1 (from
, to
, 1, 0);
1566 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1567 RET_STRING says to return the deleted text. */
1570 del_range_1 (ptrdiff_t from
, ptrdiff_t to
, bool prepare
, bool ret_string
)
1572 ptrdiff_t from_byte
, to_byte
;
1573 Lisp_Object deletion
;
1574 struct gcpro gcpro1
;
1576 /* Make args be valid */
1587 ptrdiff_t range_length
= to
- from
;
1588 prepare_to_modify_buffer (from
, to
, &from
);
1589 to
= min (ZV
, from
+ range_length
);
1592 from_byte
= CHAR_TO_BYTE (from
);
1593 to_byte
= CHAR_TO_BYTE (to
);
1595 deletion
= del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
);
1597 signal_after_change (from
, to
- from
, 0);
1598 update_compositions (from
, from
, CHECK_HEAD
);
1603 /* Like del_range_1 but args are byte positions, not char positions. */
1606 del_range_byte (ptrdiff_t from_byte
, ptrdiff_t to_byte
, bool prepare
)
1610 /* Make args be valid */
1611 if (from_byte
< BEGV_BYTE
)
1612 from_byte
= BEGV_BYTE
;
1613 if (to_byte
> ZV_BYTE
)
1616 if (to_byte
<= from_byte
)
1619 from
= BYTE_TO_CHAR (from_byte
);
1620 to
= BYTE_TO_CHAR (to_byte
);
1624 ptrdiff_t old_from
= from
, old_to
= Z
- to
;
1625 ptrdiff_t range_length
= to
- from
;
1626 prepare_to_modify_buffer (from
, to
, &from
);
1627 to
= from
+ range_length
;
1629 if (old_from
!= from
)
1630 from_byte
= CHAR_TO_BYTE (from
);
1636 else if (old_to
== Z
- to
)
1637 to_byte
= CHAR_TO_BYTE (to
);
1640 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1641 signal_after_change (from
, to
- from
, 0);
1642 update_compositions (from
, from
, CHECK_HEAD
);
1645 /* Like del_range_1, but positions are specified both as charpos
1649 del_range_both (ptrdiff_t from
, ptrdiff_t from_byte
,
1650 ptrdiff_t to
, ptrdiff_t to_byte
, bool prepare
)
1652 /* Make args be valid */
1653 if (from_byte
< BEGV_BYTE
)
1654 from_byte
= BEGV_BYTE
;
1655 if (to_byte
> ZV_BYTE
)
1658 if (to_byte
<= from_byte
)
1668 ptrdiff_t old_from
= from
, old_to
= Z
- to
;
1669 ptrdiff_t range_length
= to
- from
;
1670 prepare_to_modify_buffer (from
, to
, &from
);
1671 to
= from
+ range_length
;
1673 if (old_from
!= from
)
1674 from_byte
= CHAR_TO_BYTE (from
);
1680 else if (old_to
== Z
- to
)
1681 to_byte
= CHAR_TO_BYTE (to
);
1684 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1685 signal_after_change (from
, to
- from
, 0);
1686 update_compositions (from
, from
, CHECK_HEAD
);
1689 /* Delete a range of text, specified both as character positions
1690 and byte positions. FROM and TO are character positions,
1691 while FROM_BYTE and TO_BYTE are byte positions.
1692 If RET_STRING, the deleted area is returned as a string. */
1695 del_range_2 (ptrdiff_t from
, ptrdiff_t from_byte
,
1696 ptrdiff_t to
, ptrdiff_t to_byte
, bool ret_string
)
1698 ptrdiff_t nbytes_del
, nchars_del
;
1699 Lisp_Object deletion
;
1703 nchars_del
= to
- from
;
1704 nbytes_del
= to_byte
- from_byte
;
1706 /* Make sure the gap is somewhere in or next to what we are deleting. */
1708 gap_right (from
, from_byte
);
1710 gap_left (to
, to_byte
, 0);
1712 #ifdef BYTE_COMBINING_DEBUG
1713 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
1714 Z_BYTE
- to_byte
, from
, from_byte
))
1718 if (ret_string
|| ! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1719 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1723 /* Relocate all markers pointing into the new, larger gap
1724 to point at the end of the text before the gap.
1725 Do this before recording the deletion,
1726 so that undo handles this after reinserting the text. */
1727 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1729 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1730 record_delete (from
, deletion
);
1732 CHARS_MODIFF
= MODIFF
;
1734 /* Relocate point as if it were a marker. */
1736 adjust_point (from
- (PT
< to
? PT
: to
),
1737 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
1739 offset_intervals (current_buffer
, from
, - nchars_del
);
1741 /* Adjust the overlay center as needed. This must be done after
1742 adjusting the markers that bound the overlays. */
1743 adjust_overlays_for_delete (from
, nchars_del
);
1745 GAP_SIZE
+= nbytes_del
;
1746 ZV_BYTE
-= nbytes_del
;
1747 Z_BYTE
-= nbytes_del
;
1751 GPT_BYTE
= from_byte
;
1752 if (GAP_SIZE
> 0 && !current_buffer
->text
->inhibit_shrinking
)
1753 /* Put an anchor, unless called from decode_coding_object which
1754 needs to access the previous gap contents. */
1757 eassert (GPT
<= GPT_BYTE
);
1759 if (GPT
- BEG
< BEG_UNCHANGED
)
1760 BEG_UNCHANGED
= GPT
- BEG
;
1761 if (Z
- GPT
< END_UNCHANGED
)
1762 END_UNCHANGED
= Z
- GPT
;
1766 evaporate_overlays (from
);
1771 /* Call this if you're about to change the region of current buffer
1772 from character positions START to END. This checks the read-only
1773 properties of the region, calls the necessary modification hooks,
1774 and warns the next redisplay that it should pay attention to that
1777 If PRESERVE_CHARS_MODIFF, do not update CHARS_MODIFF.
1778 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1781 modify_region_1 (ptrdiff_t start
, ptrdiff_t end
, bool preserve_chars_modiff
)
1783 prepare_to_modify_buffer (start
, end
, NULL
);
1785 BUF_COMPUTE_UNCHANGED (current_buffer
, start
- 1, end
);
1787 if (MODIFF
<= SAVE_MODIFF
)
1788 record_first_change ();
1790 if (! preserve_chars_modiff
)
1791 CHARS_MODIFF
= MODIFF
;
1793 bset_point_before_scroll (current_buffer
, Qnil
);
1796 /* Check that it is okay to modify the buffer between START and END,
1797 which are char positions.
1799 Run the before-change-function, if any. If intervals are in use,
1800 verify that the text to be modified is not read-only, and call
1801 any modification properties the text may have.
1803 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1804 by holding its value temporarily in a marker. */
1807 prepare_to_modify_buffer (ptrdiff_t start
, ptrdiff_t end
,
1808 ptrdiff_t *preserve_ptr
)
1810 struct buffer
*base_buffer
;
1812 if (!NILP (BVAR (current_buffer
, read_only
)))
1813 Fbarf_if_buffer_read_only ();
1815 /* If we're modifying the buffer other than shown in a selected window,
1816 let redisplay consider other windows if this buffer is visible. */
1817 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
1818 && buffer_window_count (current_buffer
))
1819 ++windows_or_buffers_changed
;
1821 if (buffer_intervals (current_buffer
))
1825 Lisp_Object preserve_marker
;
1826 struct gcpro gcpro1
;
1827 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
1828 GCPRO1 (preserve_marker
);
1829 verify_interval_modification (current_buffer
, start
, end
);
1830 *preserve_ptr
= marker_position (preserve_marker
);
1831 unchain_marker (XMARKER (preserve_marker
));
1835 verify_interval_modification (current_buffer
, start
, end
);
1838 /* For indirect buffers, use the base buffer to check clashes. */
1839 if (current_buffer
->base_buffer
!= 0)
1840 base_buffer
= current_buffer
->base_buffer
;
1842 base_buffer
= current_buffer
;
1844 #ifdef CLASH_DETECTION
1845 if (!NILP (BVAR (base_buffer
, file_truename
))
1846 /* Make binding buffer-file-name to nil effective. */
1847 && !NILP (BVAR (base_buffer
, filename
))
1848 && SAVE_MODIFF
>= MODIFF
)
1849 lock_file (BVAR (base_buffer
, file_truename
));
1851 /* At least warn if this file has changed on disk since it was visited. */
1852 if (!NILP (BVAR (base_buffer
, filename
))
1853 && SAVE_MODIFF
>= MODIFF
1854 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
1855 && !NILP (Ffile_exists_p (BVAR (base_buffer
, filename
))))
1856 call1 (intern ("ask-user-about-supersession-threat"),
1857 BVAR (base_buffer
,filename
));
1858 #endif /* not CLASH_DETECTION */
1860 /* If `select-active-regions' is non-nil, save the region text. */
1861 if (!NILP (BVAR (current_buffer
, mark_active
))
1862 && !inhibit_modification_hooks
1863 && XMARKER (BVAR (current_buffer
, mark
))->buffer
1864 && NILP (Vsaved_region_selection
)
1865 && (EQ (Vselect_active_regions
, Qonly
)
1866 ? EQ (CAR_SAFE (Vtransient_mark_mode
), Qonly
)
1867 : (!NILP (Vselect_active_regions
)
1868 && !NILP (Vtransient_mark_mode
))))
1870 ptrdiff_t b
= marker_position (BVAR (current_buffer
, mark
));
1873 Vsaved_region_selection
= make_buffer_string (b
, e
, 0);
1875 Vsaved_region_selection
= make_buffer_string (e
, b
, 0);
1878 signal_before_change (start
, end
, preserve_ptr
);
1880 if (current_buffer
->newline_cache
)
1881 invalidate_region_cache (current_buffer
,
1882 current_buffer
->newline_cache
,
1883 start
- BEG
, Z
- end
);
1884 if (current_buffer
->width_run_cache
)
1885 invalidate_region_cache (current_buffer
,
1886 current_buffer
->width_run_cache
,
1887 start
- BEG
, Z
- end
);
1889 Vdeactivate_mark
= Qt
;
1892 /* These macros work with an argument named `preserve_ptr'
1893 and a local variable named `preserve_marker'. */
1895 #define PRESERVE_VALUE \
1896 if (preserve_ptr && NILP (preserve_marker)) \
1897 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
1899 #define RESTORE_VALUE \
1900 if (! NILP (preserve_marker)) \
1902 *preserve_ptr = marker_position (preserve_marker); \
1903 unchain_marker (XMARKER (preserve_marker)); \
1906 #define PRESERVE_START_END \
1907 if (NILP (start_marker)) \
1908 start_marker = Fcopy_marker (start, Qnil); \
1909 if (NILP (end_marker)) \
1910 end_marker = Fcopy_marker (end, Qnil);
1912 #define FETCH_START \
1913 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
1916 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
1918 /* Set a variable to nil if an error occurred.
1919 Don't change the variable if there was no error.
1920 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
1921 VARIABLE is the variable to maybe set to nil.
1922 NO-ERROR-FLAG is nil if there was an error,
1923 anything else meaning no error (so this function does nothing). */
1925 reset_var_on_error (Lisp_Object val
)
1927 if (NILP (XCDR (val
)))
1928 Fset (XCAR (val
), Qnil
);
1932 /* Signal a change to the buffer immediately before it happens.
1933 START_INT and END_INT are the bounds of the text to be changed.
1935 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1936 by holding its value temporarily in a marker. */
1939 signal_before_change (ptrdiff_t start_int
, ptrdiff_t end_int
,
1940 ptrdiff_t *preserve_ptr
)
1942 Lisp_Object start
, end
;
1943 Lisp_Object start_marker
, end_marker
;
1944 Lisp_Object preserve_marker
;
1945 struct gcpro gcpro1
, gcpro2
, gcpro3
;
1946 ptrdiff_t count
= SPECPDL_INDEX ();
1948 if (inhibit_modification_hooks
)
1951 start
= make_number (start_int
);
1952 end
= make_number (end_int
);
1953 preserve_marker
= Qnil
;
1954 start_marker
= Qnil
;
1956 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
1958 specbind (Qinhibit_modification_hooks
, Qt
);
1960 /* If buffer is unmodified, run a special hook for that case. The
1961 check for Vfirst_change_hook is just a minor optimization. */
1962 if (SAVE_MODIFF
>= MODIFF
1963 && !NILP (Vfirst_change_hook
))
1967 Frun_hooks (1, &Qfirst_change_hook
);
1970 /* Now run the before-change-functions if any. */
1971 if (!NILP (Vbefore_change_functions
))
1973 Lisp_Object args
[3];
1974 Lisp_Object rvoe_arg
= Fcons (Qbefore_change_functions
, Qnil
);
1979 /* Mark before-change-functions to be reset to nil in case of error. */
1980 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
1982 /* Actually run the hook functions. */
1983 args
[0] = Qbefore_change_functions
;
1984 args
[1] = FETCH_START
;
1985 args
[2] = FETCH_END
;
1986 Frun_hook_with_args (3, args
);
1988 /* There was no error: unarm the reset_on_error. */
1989 XSETCDR (rvoe_arg
, Qt
);
1992 if (buffer_has_overlays ())
1995 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
1996 FETCH_START
, FETCH_END
, Qnil
);
1999 if (! NILP (start_marker
))
2000 free_marker (start_marker
);
2001 if (! NILP (end_marker
))
2002 free_marker (end_marker
);
2006 unbind_to (count
, Qnil
);
2009 /* Signal a change immediately after it happens.
2010 CHARPOS is the character position of the start of the changed text.
2011 LENDEL is the number of characters of the text before the change.
2012 (Not the whole buffer; just the part that was changed.)
2013 LENINS is the number of characters in that part of the text
2014 after the change. */
2017 signal_after_change (ptrdiff_t charpos
, ptrdiff_t lendel
, ptrdiff_t lenins
)
2019 ptrdiff_t count
= SPECPDL_INDEX ();
2020 if (inhibit_modification_hooks
)
2023 /* If we are deferring calls to the after-change functions
2024 and there are no before-change functions,
2025 just record the args that we were going to use. */
2026 if (! NILP (Vcombine_after_change_calls
)
2027 && NILP (Vbefore_change_functions
)
2028 && !buffer_has_overlays ())
2032 if (!NILP (combine_after_change_list
)
2033 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2034 Fcombine_after_change_execute ();
2036 elt
= Fcons (make_number (charpos
- BEG
),
2037 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2038 Fcons (make_number (lenins
- lendel
), Qnil
)));
2039 combine_after_change_list
2040 = Fcons (elt
, combine_after_change_list
);
2041 combine_after_change_buffer
= Fcurrent_buffer ();
2046 if (!NILP (combine_after_change_list
))
2047 Fcombine_after_change_execute ();
2049 specbind (Qinhibit_modification_hooks
, Qt
);
2051 if (!NILP (Vafter_change_functions
))
2053 Lisp_Object args
[4];
2054 Lisp_Object rvoe_arg
= Fcons (Qafter_change_functions
, Qnil
);
2056 /* Mark after-change-functions to be reset to nil in case of error. */
2057 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2059 /* Actually run the hook functions. */
2060 args
[0] = Qafter_change_functions
;
2061 XSETFASTINT (args
[1], charpos
);
2062 XSETFASTINT (args
[2], charpos
+ lenins
);
2063 XSETFASTINT (args
[3], lendel
);
2064 Frun_hook_with_args (4, args
);
2066 /* There was no error: unarm the reset_on_error. */
2067 XSETCDR (rvoe_arg
, Qt
);
2070 if (buffer_has_overlays ())
2071 report_overlay_modification (make_number (charpos
),
2072 make_number (charpos
+ lenins
),
2074 make_number (charpos
),
2075 make_number (charpos
+ lenins
),
2076 make_number (lendel
));
2078 /* After an insertion, call the text properties
2079 insert-behind-hooks or insert-in-front-hooks. */
2081 report_interval_modification (make_number (charpos
),
2082 make_number (charpos
+ lenins
));
2084 unbind_to (count
, Qnil
);
2088 Fcombine_after_change_execute_1 (Lisp_Object val
)
2090 Vcombine_after_change_calls
= val
;
2094 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2095 Scombine_after_change_execute
, 0, 0, 0,
2096 doc
: /* This function is for use internally in `combine-after-change-calls'. */)
2099 ptrdiff_t count
= SPECPDL_INDEX ();
2100 ptrdiff_t beg
, end
, change
;
2101 ptrdiff_t begpos
, endpos
;
2104 if (NILP (combine_after_change_list
))
2107 /* It is rare for combine_after_change_buffer to be invalid, but
2108 possible. It can happen when combine-after-change-calls is
2109 non-nil, and insertion calls a file handler (e.g. through
2110 lock_file) which scribbles into a temp file -- cyd */
2111 if (!BUFFERP (combine_after_change_buffer
)
2112 || !BUFFER_LIVE_P (XBUFFER (combine_after_change_buffer
)))
2114 combine_after_change_list
= Qnil
;
2118 record_unwind_current_buffer ();
2120 Fset_buffer (combine_after_change_buffer
);
2122 /* # chars unchanged at beginning of buffer. */
2124 /* # chars unchanged at end of buffer. */
2126 /* Total amount of insertion (negative for deletion). */
2129 /* Scan the various individual changes,
2130 accumulating the range info in BEG, END and CHANGE. */
2131 for (tail
= combine_after_change_list
; CONSP (tail
);
2135 ptrdiff_t thisbeg
, thisend
, thischange
;
2137 /* Extract the info from the next element. */
2141 thisbeg
= XINT (XCAR (elt
));
2146 thisend
= XINT (XCAR (elt
));
2151 thischange
= XINT (XCAR (elt
));
2153 /* Merge this range into the accumulated range. */
2154 change
+= thischange
;
2161 /* Get the current start and end positions of the range
2162 that was changed. */
2166 /* We are about to handle these, so discard them. */
2167 combine_after_change_list
= Qnil
;
2169 /* Now run the after-change functions for real.
2170 Turn off the flag that defers them. */
2171 record_unwind_protect (Fcombine_after_change_execute_1
,
2172 Vcombine_after_change_calls
);
2173 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2174 update_compositions (begpos
, endpos
, CHECK_ALL
);
2176 return unbind_to (count
, Qnil
);
2180 syms_of_insdel (void)
2182 staticpro (&combine_after_change_list
);
2183 staticpro (&combine_after_change_buffer
);
2184 combine_after_change_list
= Qnil
;
2185 combine_after_change_buffer
= Qnil
;
2187 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls
,
2188 doc
: /* Used internally by the `combine-after-change-calls' macro. */);
2189 Vcombine_after_change_calls
= Qnil
;
2191 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks
,
2192 doc
: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2193 This affects `before-change-functions' and `after-change-functions',
2194 as well as hooks attached to text properties and overlays. */);
2195 inhibit_modification_hooks
= 0;
2196 DEFSYM (Qinhibit_modification_hooks
, "inhibit-modification-hooks");
2198 defsubr (&Scombine_after_change_execute
);