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 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
418 /* Now combine the two into one large gap. */
419 GAP_SIZE
+= old_gap_size
;
421 GPT_BYTE
= real_gap_loc_byte
;
429 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
431 /* Make the gap NBYTES_REMOVED bytes shorter. */
434 make_gap_smaller (ptrdiff_t nbytes_removed
)
437 ptrdiff_t real_gap_loc
;
438 ptrdiff_t real_gap_loc_byte
;
440 ptrdiff_t real_Z_byte
;
441 ptrdiff_t real_beg_unchanged
;
442 ptrdiff_t new_gap_size
;
444 /* Make sure the gap is at least GAP_BYTES_MIN bytes. */
445 if (GAP_SIZE
- nbytes_removed
< GAP_BYTES_MIN
)
446 nbytes_removed
= GAP_SIZE
- GAP_BYTES_MIN
;
448 /* Prevent quitting in move_gap. */
453 real_gap_loc_byte
= GPT_BYTE
;
454 new_gap_size
= GAP_SIZE
- nbytes_removed
;
456 real_Z_byte
= Z_BYTE
;
457 real_beg_unchanged
= BEG_UNCHANGED
;
459 /* Pretend that the last unwanted part of the gap is the entire gap,
460 and that the first desired part of the gap is part of the buffer
462 memset (GPT_ADDR
, 0, new_gap_size
);
464 GPT_BYTE
+= new_gap_size
;
466 Z_BYTE
+= new_gap_size
;
467 GAP_SIZE
= nbytes_removed
;
469 /* Move the unwanted pretend gap to the end of the buffer. */
470 gap_right (Z
, Z_BYTE
);
472 enlarge_buffer_text (current_buffer
, -nbytes_removed
);
474 /* Now restore the desired gap. */
475 GAP_SIZE
= new_gap_size
;
477 GPT_BYTE
= real_gap_loc_byte
;
479 Z_BYTE
= real_Z_byte
;
480 BEG_UNCHANGED
= real_beg_unchanged
;
488 #endif /* USE_MMAP_FOR_BUFFERS || REL_ALLOC || DOUG_LEA_MALLOC */
491 make_gap (ptrdiff_t nbytes_added
)
493 if (nbytes_added
>= 0)
494 make_gap_larger (nbytes_added
);
495 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
497 make_gap_smaller (-nbytes_added
);
501 /* Add NBYTES to B's gap. It's enough to temporarily
502 fake current_buffer and avoid real switch to B. */
505 make_gap_1 (struct buffer
*b
, ptrdiff_t nbytes
)
507 struct buffer
*oldb
= current_buffer
;
511 current_buffer
= oldb
;
514 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
515 FROM_MULTIBYTE says whether the incoming text is multibyte.
516 TO_MULTIBYTE says whether to store the text as multibyte.
517 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
519 Return the number of bytes stored at TO_ADDR. */
522 copy_text (const unsigned char *from_addr
, unsigned char *to_addr
,
523 ptrdiff_t nbytes
, bool from_multibyte
, bool to_multibyte
)
525 if (from_multibyte
== to_multibyte
)
527 memcpy (to_addr
, from_addr
, nbytes
);
530 else if (from_multibyte
)
532 ptrdiff_t nchars
= 0;
533 ptrdiff_t bytes_left
= nbytes
;
535 while (bytes_left
> 0)
538 c
= STRING_CHAR_AND_LENGTH (from_addr
, thislen
);
539 if (! ASCII_CHAR_P (c
))
542 from_addr
+= thislen
;
543 bytes_left
-= thislen
;
550 unsigned char *initial_to_addr
= to_addr
;
552 /* Convert single-byte to multibyte. */
555 int c
= *from_addr
++;
557 if (!ASCII_CHAR_P (c
))
559 c
= BYTE8_TO_CHAR (c
);
560 to_addr
+= CHAR_STRING (c
, to_addr
);
564 /* Special case for speed. */
565 *to_addr
++ = c
, nbytes
--;
567 return to_addr
- initial_to_addr
;
571 /* Insert a string of specified length before point.
572 This function judges multibyteness based on
573 enable_multibyte_characters in the current buffer;
574 it never converts between single-byte and multibyte.
576 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
577 prepare_to_modify_buffer could relocate the text. */
580 insert (const char *string
, ptrdiff_t nbytes
)
584 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
585 insert_1_both (string
, len
, nbytes
, 0, 1, 0);
587 signal_after_change (opoint
, 0, len
);
588 update_compositions (opoint
, PT
, CHECK_BORDER
);
592 /* Likewise, but inherit text properties from neighboring characters. */
595 insert_and_inherit (const char *string
, ptrdiff_t nbytes
)
599 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
600 insert_1_both (string
, len
, nbytes
, 1, 1, 0);
602 signal_after_change (opoint
, 0, len
);
603 update_compositions (opoint
, PT
, CHECK_BORDER
);
607 /* Insert the character C before point. Do not inherit text properties. */
612 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
615 if (! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
616 len
= CHAR_STRING (c
, str
);
623 insert ((char *) str
, len
);
626 /* Insert the null-terminated string S before point. */
629 insert_string (const char *s
)
631 insert (s
, strlen (s
));
634 /* Like `insert' except that all markers pointing at the place where
635 the insertion happens are adjusted to point after it.
636 Don't use this function to insert part of a Lisp string,
637 since gc could happen and relocate it. */
640 insert_before_markers (const char *string
, ptrdiff_t nbytes
)
644 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
645 insert_1_both (string
, len
, nbytes
, 0, 1, 1);
647 signal_after_change (opoint
, 0, len
);
648 update_compositions (opoint
, PT
, CHECK_BORDER
);
652 /* Likewise, but inherit text properties from neighboring characters. */
655 insert_before_markers_and_inherit (const char *string
,
660 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
661 insert_1_both (string
, len
, nbytes
, 1, 1, 1);
663 signal_after_change (opoint
, 0, len
);
664 update_compositions (opoint
, PT
, CHECK_BORDER
);
668 /* Subroutine used by the insert functions above. */
671 insert_1 (const char *string
, ptrdiff_t nbytes
,
672 bool inherit
, bool prepare
, bool before_markers
)
674 insert_1_both (string
, chars_in_text ((unsigned char *) string
, nbytes
),
675 nbytes
, inherit
, prepare
, before_markers
);
679 #ifdef BYTE_COMBINING_DEBUG
681 /* See if the bytes before POS/POS_BYTE combine with bytes
682 at the start of STRING to form a single character.
683 If so, return the number of bytes at the start of STRING
684 which combine in this way. Otherwise, return 0. */
687 count_combining_before (const unsigned char *string
, ptrdiff_t length
,
688 ptrdiff_t pos
, ptrdiff_t pos_byte
)
690 int len
, combining_bytes
;
691 const unsigned char *p
;
693 if (NILP (current_buffer
->enable_multibyte_characters
))
696 /* At first, we can exclude the following cases:
697 (1) STRING[0] can't be a following byte of multibyte sequence.
698 (2) POS is the start of the current buffer.
699 (3) A character before POS is not a multibyte character. */
700 if (length
== 0 || CHAR_HEAD_P (*string
)) /* case (1) */
702 if (pos_byte
== BEG_BYTE
) /* case (2) */
705 p
= BYTE_POS_ADDR (pos_byte
- 1);
706 while (! CHAR_HEAD_P (*p
)) p
--, len
++;
707 if (! LEADING_CODE_P (*p
)) /* case (3) */
710 combining_bytes
= BYTES_BY_CHAR_HEAD (*p
) - len
;
711 if (combining_bytes
<= 0)
712 /* The character preceding POS is, complete and no room for
713 combining bytes (combining_bytes == 0), or an independent 8-bit
714 character (combining_bytes < 0). */
717 /* We have a combination situation. Count the bytes at STRING that
720 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
723 return (combining_bytes
< p
- string
? combining_bytes
: p
- string
);
726 /* See if the bytes after POS/POS_BYTE combine with bytes
727 at the end of STRING to form a single character.
728 If so, return the number of bytes after POS/POS_BYTE
729 which combine in this way. Otherwise, return 0. */
732 count_combining_after (const unsigned char *string
,
733 ptrdiff_t length
, ptrdiff_t pos
, ptrdiff_t pos_byte
)
735 ptrdiff_t opos_byte
= pos_byte
;
740 if (NILP (current_buffer
->enable_multibyte_characters
))
743 /* At first, we can exclude the following cases:
744 (1) The last byte of STRING is an ASCII.
745 (2) POS is the last of the current buffer.
746 (3) A character at POS can't be a following byte of multibyte
748 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1])) /* case (1) */
750 if (pos_byte
== Z_BYTE
) /* case (2) */
752 bufp
= BYTE_POS_ADDR (pos_byte
);
753 if (CHAR_HEAD_P (*bufp
)) /* case (3) */
757 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
763 /* All characters in STRING are not character head. We must
764 check also preceding bytes at POS. We are sure that the gap
766 unsigned char *p
= BEG_ADDR
;
768 while (i
>= 0 && ! CHAR_HEAD_P (p
[i
]))
770 if (i
< 0 || !LEADING_CODE_P (p
[i
]))
773 bytes
= BYTES_BY_CHAR_HEAD (p
[i
]);
774 return (bytes
<= pos_byte
- 1 - i
+ length
776 : bytes
- (pos_byte
- 1 - i
+ length
));
778 if (!LEADING_CODE_P (string
[i
]))
781 bytes
= BYTES_BY_CHAR_HEAD (string
[i
]) - (length
- i
);
783 while (!CHAR_HEAD_P (*bufp
)) bufp
++, pos_byte
++;
785 return (bytes
<= pos_byte
- opos_byte
? bytes
: pos_byte
- opos_byte
);
791 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
792 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
793 are the same as in insert_1. */
796 insert_1_both (const char *string
,
797 ptrdiff_t nchars
, ptrdiff_t nbytes
,
798 bool inherit
, bool prepare
, bool before_markers
)
803 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
807 /* Do this before moving and increasing the gap,
808 because the before-change hooks might move the gap
809 or make it smaller. */
810 prepare_to_modify_buffer (PT
, PT
, NULL
);
813 move_gap_both (PT
, PT_BYTE
);
814 if (GAP_SIZE
< nbytes
)
815 make_gap (nbytes
- GAP_SIZE
);
817 #ifdef BYTE_COMBINING_DEBUG
818 if (count_combining_before (string
, nbytes
, PT
, PT_BYTE
)
819 || count_combining_after (string
, nbytes
, PT
, PT_BYTE
))
823 /* Record deletion of the surrounding text that combines with
824 the insertion. This, together with recording the insertion,
825 will add up to the right stuff in the undo list. */
826 record_insert (PT
, nchars
);
828 CHARS_MODIFF
= MODIFF
;
830 memcpy (GPT_ADDR
, string
, nbytes
);
839 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
841 eassert (GPT
<= GPT_BYTE
);
843 /* The insert may have been in the unchanged region, so check again. */
844 if (Z
- GPT
< END_UNCHANGED
)
845 END_UNCHANGED
= Z
- GPT
;
847 adjust_overlays_for_insert (PT
, nchars
);
848 adjust_markers_for_insert (PT
, PT_BYTE
,
849 PT
+ nchars
, PT_BYTE
+ nbytes
,
852 offset_intervals (current_buffer
, PT
, nchars
);
854 if (!inherit
&& buffer_intervals (current_buffer
))
855 set_text_properties (make_number (PT
), make_number (PT
+ nchars
),
858 adjust_point (nchars
, nbytes
);
863 /* Insert the part of the text of STRING, a Lisp object assumed to be
864 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
865 starting at position POS / POS_BYTE. If the text of STRING has properties,
866 copy them into the buffer.
868 It does not work to use `insert' for this, because a GC could happen
869 before we copy the stuff into the buffer, and relocate the string
870 without insert noticing. */
873 insert_from_string (Lisp_Object string
, ptrdiff_t pos
, ptrdiff_t pos_byte
,
874 ptrdiff_t length
, ptrdiff_t length_byte
, bool inherit
)
876 ptrdiff_t opoint
= PT
;
878 if (SCHARS (string
) == 0)
881 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
883 signal_after_change (opoint
, 0, PT
- opoint
);
884 update_compositions (opoint
, PT
, CHECK_BORDER
);
887 /* Like `insert_from_string' except that all markers pointing
888 at the place where the insertion happens are adjusted to point after it. */
891 insert_from_string_before_markers (Lisp_Object string
,
892 ptrdiff_t pos
, ptrdiff_t pos_byte
,
893 ptrdiff_t length
, ptrdiff_t length_byte
,
896 ptrdiff_t opoint
= PT
;
898 if (SCHARS (string
) == 0)
901 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
903 signal_after_change (opoint
, 0, PT
- opoint
);
904 update_compositions (opoint
, PT
, CHECK_BORDER
);
907 /* Subroutine of the insertion functions above. */
910 insert_from_string_1 (Lisp_Object string
, ptrdiff_t pos
, ptrdiff_t pos_byte
,
911 ptrdiff_t nchars
, ptrdiff_t nbytes
,
912 bool inherit
, bool before_markers
)
915 ptrdiff_t outgoing_nbytes
= nbytes
;
918 /* Make OUTGOING_NBYTES describe the text
919 as it will be inserted in this buffer. */
921 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
922 outgoing_nbytes
= nchars
;
923 else if (! STRING_MULTIBYTE (string
))
925 = count_size_as_multibyte (SDATA (string
) + pos_byte
,
929 /* Do this before moving and increasing the gap,
930 because the before-change hooks might move the gap
931 or make it smaller. */
932 prepare_to_modify_buffer (PT
, PT
, NULL
);
935 move_gap_both (PT
, PT_BYTE
);
936 if (GAP_SIZE
< outgoing_nbytes
)
937 make_gap (outgoing_nbytes
- GAP_SIZE
);
940 /* Copy the string text into the buffer, perhaps converting
941 between single-byte and multibyte. */
942 copy_text (SDATA (string
) + pos_byte
, GPT_ADDR
, nbytes
,
943 STRING_MULTIBYTE (string
),
944 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
946 #ifdef BYTE_COMBINING_DEBUG
947 /* We have copied text into the gap, but we have not altered
948 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
949 to these functions and get the same results as we would
950 have got earlier on. Meanwhile, PT_ADDR does point to
951 the text that has been stored by copy_text. */
952 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
953 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
957 record_insert (PT
, nchars
);
959 CHARS_MODIFF
= MODIFF
;
961 GAP_SIZE
-= outgoing_nbytes
;
965 GPT_BYTE
+= outgoing_nbytes
;
966 ZV_BYTE
+= outgoing_nbytes
;
967 Z_BYTE
+= outgoing_nbytes
;
968 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
970 eassert (GPT
<= GPT_BYTE
);
972 /* The insert may have been in the unchanged region, so check again. */
973 if (Z
- GPT
< END_UNCHANGED
)
974 END_UNCHANGED
= Z
- GPT
;
976 adjust_overlays_for_insert (PT
, nchars
);
977 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
978 PT_BYTE
+ outgoing_nbytes
,
981 offset_intervals (current_buffer
, PT
, nchars
);
983 intervals
= string_intervals (string
);
984 /* Get the intervals for the part of the string we are inserting. */
985 if (nbytes
< SBYTES (string
))
986 intervals
= copy_intervals (intervals
, pos
, nchars
);
988 /* Insert those intervals. */
989 graft_intervals_into_buffer (intervals
, PT
, nchars
,
990 current_buffer
, inherit
);
992 adjust_point (nchars
, outgoing_nbytes
);
997 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
998 starting at GPT_ADDR. */
1001 insert_from_gap (ptrdiff_t nchars
, ptrdiff_t nbytes
)
1003 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1006 record_insert (GPT
, nchars
);
1016 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1018 eassert (GPT
<= GPT_BYTE
);
1020 adjust_overlays_for_insert (GPT
- nchars
, nchars
);
1021 adjust_markers_for_insert (GPT
- nchars
, GPT_BYTE
- nbytes
,
1024 if (buffer_intervals (current_buffer
))
1026 offset_intervals (current_buffer
, GPT
- nchars
, nchars
);
1027 graft_intervals_into_buffer (NULL
, GPT
- nchars
, nchars
,
1031 if (GPT
- nchars
< PT
)
1032 adjust_point (nchars
, nbytes
);
1037 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1038 current buffer. If the text in BUF has properties, they are absorbed
1039 into the current buffer.
1041 It does not work to use `insert' for this, because a malloc could happen
1042 and relocate BUF's text before the copy happens. */
1045 insert_from_buffer (struct buffer
*buf
,
1046 ptrdiff_t charpos
, ptrdiff_t nchars
, bool inherit
)
1048 ptrdiff_t opoint
= PT
;
1050 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1051 signal_after_change (opoint
, 0, PT
- opoint
);
1052 update_compositions (opoint
, PT
, CHECK_BORDER
);
1056 insert_from_buffer_1 (struct buffer
*buf
,
1057 ptrdiff_t from
, ptrdiff_t nchars
, bool inherit
)
1059 ptrdiff_t chunk
, chunk_expanded
;
1060 ptrdiff_t from_byte
= buf_charpos_to_bytepos (buf
, from
);
1061 ptrdiff_t to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1062 ptrdiff_t incoming_nbytes
= to_byte
- from_byte
;
1063 ptrdiff_t outgoing_nbytes
= incoming_nbytes
;
1066 /* Make OUTGOING_NBYTES describe the text
1067 as it will be inserted in this buffer. */
1069 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1070 outgoing_nbytes
= nchars
;
1071 else if (NILP (BVAR (buf
, enable_multibyte_characters
)))
1073 ptrdiff_t outgoing_before_gap
= 0;
1074 ptrdiff_t outgoing_after_gap
= 0;
1076 if (from
< BUF_GPT (buf
))
1078 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1079 if (chunk
> incoming_nbytes
)
1080 chunk
= incoming_nbytes
;
1082 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1088 if (chunk
< incoming_nbytes
)
1090 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
,
1092 incoming_nbytes
- chunk
);
1094 outgoing_nbytes
= outgoing_before_gap
+ outgoing_after_gap
;
1097 /* Do this before moving and increasing the gap,
1098 because the before-change hooks might move the gap
1099 or make it smaller. */
1100 prepare_to_modify_buffer (PT
, PT
, NULL
);
1103 move_gap_both (PT
, PT_BYTE
);
1104 if (GAP_SIZE
< outgoing_nbytes
)
1105 make_gap (outgoing_nbytes
- GAP_SIZE
);
1107 if (from
< BUF_GPT (buf
))
1109 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1110 if (chunk
> incoming_nbytes
)
1111 chunk
= incoming_nbytes
;
1112 /* Record number of output bytes, so we know where
1113 to put the output from the second copy_text. */
1115 = copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1117 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1118 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1121 chunk_expanded
= chunk
= 0;
1123 if (chunk
< incoming_nbytes
)
1124 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1125 GPT_ADDR
+ chunk_expanded
, incoming_nbytes
- chunk
,
1126 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1127 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1129 #ifdef BYTE_COMBINING_DEBUG
1130 /* We have copied text into the gap, but we have not altered
1131 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1132 to these functions and get the same results as we would
1133 have got earlier on. Meanwhile, GPT_ADDR does point to
1134 the text that has been stored by copy_text. */
1135 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1136 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1140 record_insert (PT
, nchars
);
1142 CHARS_MODIFF
= MODIFF
;
1144 GAP_SIZE
-= outgoing_nbytes
;
1148 GPT_BYTE
+= outgoing_nbytes
;
1149 ZV_BYTE
+= outgoing_nbytes
;
1150 Z_BYTE
+= outgoing_nbytes
;
1151 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1153 eassert (GPT
<= GPT_BYTE
);
1155 /* The insert may have been in the unchanged region, so check again. */
1156 if (Z
- GPT
< END_UNCHANGED
)
1157 END_UNCHANGED
= Z
- GPT
;
1159 adjust_overlays_for_insert (PT
, nchars
);
1160 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1161 PT_BYTE
+ outgoing_nbytes
,
1164 offset_intervals (current_buffer
, PT
, nchars
);
1166 /* Get the intervals for the part of the string we are inserting. */
1167 intervals
= buffer_intervals (buf
);
1168 if (nchars
< BUF_Z (buf
) - BUF_BEG (buf
))
1170 if (buf
== current_buffer
&& PT
<= from
)
1172 intervals
= copy_intervals (intervals
, from
, nchars
);
1175 /* Insert those intervals. */
1176 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1178 adjust_point (nchars
, outgoing_nbytes
);
1181 /* Record undo information and adjust markers and position keepers for
1182 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1183 chars (LEN_BYTE bytes) which resides in the gap just after
1186 PREV_TEXT nil means the new text was just inserted. */
1189 adjust_after_replace (ptrdiff_t from
, ptrdiff_t from_byte
,
1190 Lisp_Object prev_text
, ptrdiff_t len
, ptrdiff_t len_byte
)
1192 ptrdiff_t nchars_del
= 0, nbytes_del
= 0;
1194 #ifdef BYTE_COMBINING_DEBUG
1195 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1196 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1200 if (STRINGP (prev_text
))
1202 nchars_del
= SCHARS (prev_text
);
1203 nbytes_del
= SBYTES (prev_text
);
1206 /* Update various buffer positions for the new text. */
1207 GAP_SIZE
-= len_byte
;
1209 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1210 GPT
+= len
; GPT_BYTE
+= len_byte
;
1211 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1214 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1217 adjust_markers_for_insert (from
, from_byte
,
1218 from
+ len
, from_byte
+ len_byte
, 0);
1220 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1223 record_delete (from
, prev_text
);
1224 record_insert (from
, len
);
1227 if (len
> nchars_del
)
1228 adjust_overlays_for_insert (from
, len
- nchars_del
);
1229 else if (len
< nchars_del
)
1230 adjust_overlays_for_delete (from
, nchars_del
- len
);
1232 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1235 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1237 /* As byte combining will decrease Z, we must check this again. */
1238 if (Z
- GPT
< END_UNCHANGED
)
1239 END_UNCHANGED
= Z
- GPT
;
1244 evaporate_overlays (from
);
1246 CHARS_MODIFF
= MODIFF
;
1249 /* Record undo information, adjust markers and position keepers for an
1250 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1251 text already exists in the current buffer but character length (TO
1252 - FROM) may be incorrect, the correct length is NEWLEN. */
1255 adjust_after_insert (ptrdiff_t from
, ptrdiff_t from_byte
,
1256 ptrdiff_t to
, ptrdiff_t to_byte
, ptrdiff_t newlen
)
1258 ptrdiff_t len
= to
- from
, len_byte
= to_byte
- from_byte
;
1261 move_gap_both (to
, to_byte
);
1262 GAP_SIZE
+= len_byte
;
1263 GPT
-= len
; GPT_BYTE
-= len_byte
;
1264 ZV
-= len
; ZV_BYTE
-= len_byte
;
1265 Z
-= len
; Z_BYTE
-= len_byte
;
1266 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1269 /* Replace the text from character positions FROM to TO with NEW,
1270 If PREPARE, call prepare_to_modify_buffer.
1271 If INHERIT, the newly inserted text should inherit text properties
1272 from the surrounding non-deleted text. */
1274 /* Note that this does not yet handle markers quite right.
1275 Also it needs to record a single undo-entry that does a replacement
1276 rather than a separate delete and insert.
1277 That way, undo will also handle markers properly.
1279 But if MARKERS is 0, don't relocate markers. */
1282 replace_range (ptrdiff_t from
, ptrdiff_t to
, Lisp_Object
new,
1283 bool prepare
, bool inherit
, bool markers
)
1285 ptrdiff_t inschars
= SCHARS (new);
1286 ptrdiff_t insbytes
= SBYTES (new);
1287 ptrdiff_t from_byte
, to_byte
;
1288 ptrdiff_t nbytes_del
, nchars_del
;
1289 struct gcpro gcpro1
;
1291 ptrdiff_t outgoing_insbytes
= insbytes
;
1292 Lisp_Object deletion
;
1301 ptrdiff_t range_length
= to
- from
;
1302 prepare_to_modify_buffer (from
, to
, &from
);
1303 to
= from
+ range_length
;
1308 /* Make args be valid. */
1314 from_byte
= CHAR_TO_BYTE (from
);
1315 to_byte
= CHAR_TO_BYTE (to
);
1317 nchars_del
= to
- from
;
1318 nbytes_del
= to_byte
- from_byte
;
1320 if (nbytes_del
<= 0 && insbytes
== 0)
1323 /* Make OUTGOING_INSBYTES describe the text
1324 as it will be inserted in this buffer. */
1326 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1327 outgoing_insbytes
= inschars
;
1328 else if (! STRING_MULTIBYTE (new))
1330 = count_size_as_multibyte (SDATA (new), insbytes
);
1334 /* Make sure the gap is somewhere in or next to what we are deleting. */
1336 gap_right (from
, from_byte
);
1338 gap_left (to
, to_byte
, 0);
1340 /* Even if we don't record for undo, we must keep the original text
1341 because we may have to recover it because of inappropriate byte
1343 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1344 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1346 GAP_SIZE
+= nbytes_del
;
1349 ZV_BYTE
-= nbytes_del
;
1350 Z_BYTE
-= nbytes_del
;
1352 GPT_BYTE
= from_byte
;
1353 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1355 eassert (GPT
<= GPT_BYTE
);
1357 if (GPT
- BEG
< BEG_UNCHANGED
)
1358 BEG_UNCHANGED
= GPT
- BEG
;
1359 if (Z
- GPT
< END_UNCHANGED
)
1360 END_UNCHANGED
= Z
- GPT
;
1362 if (GAP_SIZE
< outgoing_insbytes
)
1363 make_gap (outgoing_insbytes
- GAP_SIZE
);
1365 /* Copy the string text into the buffer, perhaps converting
1366 between single-byte and multibyte. */
1367 copy_text (SDATA (new), GPT_ADDR
, insbytes
,
1368 STRING_MULTIBYTE (new),
1369 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1371 #ifdef BYTE_COMBINING_DEBUG
1372 /* We have copied text into the gap, but we have not marked
1373 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1374 here, for both the previous text and the following text.
1375 Meanwhile, GPT_ADDR does point to
1376 the text that has been stored by copy_text. */
1377 if (count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
)
1378 || count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
))
1382 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1384 /* Record the insertion first, so that when we undo,
1385 the deletion will be undone first. Thus, undo
1386 will insert before deleting, and thus will keep
1387 the markers before and after this text separate. */
1388 record_insert (from
+ SCHARS (deletion
), inschars
);
1389 record_delete (from
, deletion
);
1392 GAP_SIZE
-= outgoing_insbytes
;
1396 GPT_BYTE
+= outgoing_insbytes
;
1397 ZV_BYTE
+= outgoing_insbytes
;
1398 Z_BYTE
+= outgoing_insbytes
;
1399 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1401 eassert (GPT
<= GPT_BYTE
);
1403 /* Adjust markers for the deletion and the insertion. */
1405 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1406 inschars
, outgoing_insbytes
);
1408 /* Adjust the overlay center as needed. This must be done after
1409 adjusting the markers that bound the overlays. */
1410 adjust_overlays_for_delete (from
, nchars_del
);
1411 adjust_overlays_for_insert (from
, inschars
);
1413 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1415 /* Get the intervals for the part of the string we are inserting--
1416 not including the combined-before bytes. */
1417 intervals
= string_intervals (new);
1418 /* Insert those intervals. */
1419 graft_intervals_into_buffer (intervals
, from
, inschars
,
1420 current_buffer
, inherit
);
1422 /* Relocate point as if it were a marker. */
1424 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1425 (from_byte
+ outgoing_insbytes
1426 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1428 if (outgoing_insbytes
== 0)
1429 evaporate_overlays (from
);
1434 CHARS_MODIFF
= MODIFF
;
1437 signal_after_change (from
, nchars_del
, GPT
- from
);
1438 update_compositions (from
, GPT
, CHECK_BORDER
);
1441 /* Replace the text from character positions FROM to TO with
1442 the text in INS of length INSCHARS.
1443 Keep the text properties that applied to the old characters
1444 (extending them to all the new chars if there are more new chars).
1446 Note that this does not yet handle markers quite right.
1448 If MARKERS, relocate markers.
1450 Unlike most functions at this level, never call
1451 prepare_to_modify_buffer and never call signal_after_change. */
1454 replace_range_2 (ptrdiff_t from
, ptrdiff_t from_byte
,
1455 ptrdiff_t to
, ptrdiff_t to_byte
,
1456 const char *ins
, ptrdiff_t inschars
, ptrdiff_t insbytes
,
1459 ptrdiff_t nbytes_del
, nchars_del
;
1463 nchars_del
= to
- from
;
1464 nbytes_del
= to_byte
- from_byte
;
1466 if (nbytes_del
<= 0 && insbytes
== 0)
1469 /* Make sure the gap is somewhere in or next to what we are deleting. */
1471 gap_right (from
, from_byte
);
1473 gap_left (to
, to_byte
, 0);
1475 GAP_SIZE
+= nbytes_del
;
1478 ZV_BYTE
-= nbytes_del
;
1479 Z_BYTE
-= nbytes_del
;
1481 GPT_BYTE
= from_byte
;
1482 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1484 eassert (GPT
<= GPT_BYTE
);
1486 if (GPT
- BEG
< BEG_UNCHANGED
)
1487 BEG_UNCHANGED
= GPT
- BEG
;
1488 if (Z
- GPT
< END_UNCHANGED
)
1489 END_UNCHANGED
= Z
- GPT
;
1491 if (GAP_SIZE
< insbytes
)
1492 make_gap (insbytes
- GAP_SIZE
);
1494 /* Copy the replacement text into the buffer. */
1495 memcpy (GPT_ADDR
, ins
, insbytes
);
1497 #ifdef BYTE_COMBINING_DEBUG
1498 /* We have copied text into the gap, but we have not marked
1499 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1500 here, for both the previous text and the following text.
1501 Meanwhile, GPT_ADDR does point to
1502 the text that has been stored by copy_text. */
1503 if (count_combining_before (GPT_ADDR
, insbytes
, from
, from_byte
)
1504 || count_combining_after (GPT_ADDR
, insbytes
, from
, from_byte
))
1508 GAP_SIZE
-= insbytes
;
1512 GPT_BYTE
+= insbytes
;
1513 ZV_BYTE
+= insbytes
;
1515 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1517 eassert (GPT
<= GPT_BYTE
);
1519 /* Adjust markers for the deletion and the insertion. */
1521 && ! (nchars_del
== 1 && inschars
== 1 && nbytes_del
== insbytes
))
1522 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1523 inschars
, insbytes
);
1525 /* Adjust the overlay center as needed. This must be done after
1526 adjusting the markers that bound the overlays. */
1527 if (nchars_del
!= inschars
)
1529 adjust_overlays_for_insert (from
, inschars
);
1530 adjust_overlays_for_delete (from
+ inschars
, nchars_del
);
1533 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1535 /* Relocate point as if it were a marker. */
1536 if (from
< PT
&& (nchars_del
!= inschars
|| nbytes_del
!= insbytes
))
1539 /* PT was within the deleted text. Move it to FROM. */
1540 adjust_point (from
- PT
, from_byte
- PT_BYTE
);
1542 adjust_point (inschars
- nchars_del
, insbytes
- nbytes_del
);
1546 evaporate_overlays (from
);
1551 CHARS_MODIFF
= MODIFF
;
1554 /* Delete characters in current buffer
1555 from FROM up to (but not including) TO.
1556 If TO comes before FROM, we delete nothing. */
1559 del_range (ptrdiff_t from
, ptrdiff_t to
)
1561 del_range_1 (from
, to
, 1, 0);
1564 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1565 RET_STRING says to return the deleted text. */
1568 del_range_1 (ptrdiff_t from
, ptrdiff_t to
, bool prepare
, bool ret_string
)
1570 ptrdiff_t from_byte
, to_byte
;
1571 Lisp_Object deletion
;
1572 struct gcpro gcpro1
;
1574 /* Make args be valid */
1585 ptrdiff_t range_length
= to
- from
;
1586 prepare_to_modify_buffer (from
, to
, &from
);
1587 to
= min (ZV
, from
+ range_length
);
1590 from_byte
= CHAR_TO_BYTE (from
);
1591 to_byte
= CHAR_TO_BYTE (to
);
1593 deletion
= del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
);
1595 signal_after_change (from
, to
- from
, 0);
1596 update_compositions (from
, from
, CHECK_HEAD
);
1601 /* Like del_range_1 but args are byte positions, not char positions. */
1604 del_range_byte (ptrdiff_t from_byte
, ptrdiff_t to_byte
, bool prepare
)
1608 /* Make args be valid */
1609 if (from_byte
< BEGV_BYTE
)
1610 from_byte
= BEGV_BYTE
;
1611 if (to_byte
> ZV_BYTE
)
1614 if (to_byte
<= from_byte
)
1617 from
= BYTE_TO_CHAR (from_byte
);
1618 to
= BYTE_TO_CHAR (to_byte
);
1622 ptrdiff_t old_from
= from
, old_to
= Z
- to
;
1623 ptrdiff_t range_length
= to
- from
;
1624 prepare_to_modify_buffer (from
, to
, &from
);
1625 to
= from
+ range_length
;
1627 if (old_from
!= from
)
1628 from_byte
= CHAR_TO_BYTE (from
);
1634 else if (old_to
== Z
- to
)
1635 to_byte
= CHAR_TO_BYTE (to
);
1638 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1639 signal_after_change (from
, to
- from
, 0);
1640 update_compositions (from
, from
, CHECK_HEAD
);
1643 /* Like del_range_1, but positions are specified both as charpos
1647 del_range_both (ptrdiff_t from
, ptrdiff_t from_byte
,
1648 ptrdiff_t to
, ptrdiff_t to_byte
, bool prepare
)
1650 /* Make args be valid */
1651 if (from_byte
< BEGV_BYTE
)
1652 from_byte
= BEGV_BYTE
;
1653 if (to_byte
> ZV_BYTE
)
1656 if (to_byte
<= from_byte
)
1666 ptrdiff_t old_from
= from
, old_to
= Z
- to
;
1667 ptrdiff_t range_length
= to
- from
;
1668 prepare_to_modify_buffer (from
, to
, &from
);
1669 to
= from
+ range_length
;
1671 if (old_from
!= from
)
1672 from_byte
= CHAR_TO_BYTE (from
);
1678 else if (old_to
== Z
- to
)
1679 to_byte
= CHAR_TO_BYTE (to
);
1682 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1683 signal_after_change (from
, to
- from
, 0);
1684 update_compositions (from
, from
, CHECK_HEAD
);
1687 /* Delete a range of text, specified both as character positions
1688 and byte positions. FROM and TO are character positions,
1689 while FROM_BYTE and TO_BYTE are byte positions.
1690 If RET_STRING, the deleted area is returned as a string. */
1693 del_range_2 (ptrdiff_t from
, ptrdiff_t from_byte
,
1694 ptrdiff_t to
, ptrdiff_t to_byte
, bool ret_string
)
1696 ptrdiff_t nbytes_del
, nchars_del
;
1697 Lisp_Object deletion
;
1701 nchars_del
= to
- from
;
1702 nbytes_del
= to_byte
- from_byte
;
1704 /* Make sure the gap is somewhere in or next to what we are deleting. */
1706 gap_right (from
, from_byte
);
1708 gap_left (to
, to_byte
, 0);
1710 #ifdef BYTE_COMBINING_DEBUG
1711 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
1712 Z_BYTE
- to_byte
, from
, from_byte
))
1716 if (ret_string
|| ! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1717 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1721 /* Relocate all markers pointing into the new, larger gap
1722 to point at the end of the text before the gap.
1723 Do this before recording the deletion,
1724 so that undo handles this after reinserting the text. */
1725 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1727 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1728 record_delete (from
, deletion
);
1730 CHARS_MODIFF
= MODIFF
;
1732 /* Relocate point as if it were a marker. */
1734 adjust_point (from
- (PT
< to
? PT
: to
),
1735 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
1737 offset_intervals (current_buffer
, from
, - nchars_del
);
1739 /* Adjust the overlay center as needed. This must be done after
1740 adjusting the markers that bound the overlays. */
1741 adjust_overlays_for_delete (from
, nchars_del
);
1743 GAP_SIZE
+= nbytes_del
;
1744 ZV_BYTE
-= nbytes_del
;
1745 Z_BYTE
-= nbytes_del
;
1749 GPT_BYTE
= from_byte
;
1750 if (GAP_SIZE
> 0 && !current_buffer
->text
->inhibit_shrinking
)
1751 /* Put an anchor, unless called from decode_coding_object which
1752 needs to access the previous gap contents. */
1755 eassert (GPT
<= GPT_BYTE
);
1757 if (GPT
- BEG
< BEG_UNCHANGED
)
1758 BEG_UNCHANGED
= GPT
- BEG
;
1759 if (Z
- GPT
< END_UNCHANGED
)
1760 END_UNCHANGED
= Z
- GPT
;
1764 evaporate_overlays (from
);
1769 /* Call this if you're about to change the region of current buffer
1770 from character positions START to END. This checks the read-only
1771 properties of the region, calls the necessary modification hooks,
1772 and warns the next redisplay that it should pay attention to that
1775 If PRESERVE_CHARS_MODIFF, do not update CHARS_MODIFF.
1776 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1779 modify_region_1 (ptrdiff_t start
, ptrdiff_t end
, bool preserve_chars_modiff
)
1781 prepare_to_modify_buffer (start
, end
, NULL
);
1783 BUF_COMPUTE_UNCHANGED (current_buffer
, start
- 1, end
);
1785 if (MODIFF
<= SAVE_MODIFF
)
1786 record_first_change ();
1788 if (! preserve_chars_modiff
)
1789 CHARS_MODIFF
= MODIFF
;
1791 bset_point_before_scroll (current_buffer
, Qnil
);
1794 /* Check that it is okay to modify the buffer between START and END,
1795 which are char positions.
1797 Run the before-change-function, if any. If intervals are in use,
1798 verify that the text to be modified is not read-only, and call
1799 any modification properties the text may have.
1801 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1802 by holding its value temporarily in a marker. */
1805 prepare_to_modify_buffer (ptrdiff_t start
, ptrdiff_t end
,
1806 ptrdiff_t *preserve_ptr
)
1808 struct buffer
*base_buffer
;
1810 if (!NILP (BVAR (current_buffer
, read_only
)))
1811 Fbarf_if_buffer_read_only ();
1813 /* If we're modifying the buffer other than shown in a selected window,
1814 let redisplay consider other windows if this buffer is visible. */
1815 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
1816 && buffer_window_count (current_buffer
))
1817 ++windows_or_buffers_changed
;
1819 if (buffer_intervals (current_buffer
))
1823 Lisp_Object preserve_marker
;
1824 struct gcpro gcpro1
;
1825 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
1826 GCPRO1 (preserve_marker
);
1827 verify_interval_modification (current_buffer
, start
, end
);
1828 *preserve_ptr
= marker_position (preserve_marker
);
1829 unchain_marker (XMARKER (preserve_marker
));
1833 verify_interval_modification (current_buffer
, start
, end
);
1836 /* For indirect buffers, use the base buffer to check clashes. */
1837 if (current_buffer
->base_buffer
!= 0)
1838 base_buffer
= current_buffer
->base_buffer
;
1840 base_buffer
= current_buffer
;
1842 #ifdef CLASH_DETECTION
1843 if (!NILP (BVAR (base_buffer
, file_truename
))
1844 /* Make binding buffer-file-name to nil effective. */
1845 && !NILP (BVAR (base_buffer
, filename
))
1846 && SAVE_MODIFF
>= MODIFF
)
1847 lock_file (BVAR (base_buffer
, file_truename
));
1849 /* At least warn if this file has changed on disk since it was visited. */
1850 if (!NILP (BVAR (base_buffer
, filename
))
1851 && SAVE_MODIFF
>= MODIFF
1852 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
1853 && !NILP (Ffile_exists_p (BVAR (base_buffer
, filename
))))
1854 call1 (intern ("ask-user-about-supersession-threat"),
1855 BVAR (base_buffer
,filename
));
1856 #endif /* not CLASH_DETECTION */
1858 /* If `select-active-regions' is non-nil, save the region text. */
1859 if (!NILP (BVAR (current_buffer
, mark_active
))
1860 && !inhibit_modification_hooks
1861 && XMARKER (BVAR (current_buffer
, mark
))->buffer
1862 && NILP (Vsaved_region_selection
)
1863 && (EQ (Vselect_active_regions
, Qonly
)
1864 ? EQ (CAR_SAFE (Vtransient_mark_mode
), Qonly
)
1865 : (!NILP (Vselect_active_regions
)
1866 && !NILP (Vtransient_mark_mode
))))
1868 ptrdiff_t b
= marker_position (BVAR (current_buffer
, mark
));
1871 Vsaved_region_selection
= make_buffer_string (b
, e
, 0);
1873 Vsaved_region_selection
= make_buffer_string (e
, b
, 0);
1876 signal_before_change (start
, end
, preserve_ptr
);
1878 if (current_buffer
->newline_cache
)
1879 invalidate_region_cache (current_buffer
,
1880 current_buffer
->newline_cache
,
1881 start
- BEG
, Z
- end
);
1882 if (current_buffer
->width_run_cache
)
1883 invalidate_region_cache (current_buffer
,
1884 current_buffer
->width_run_cache
,
1885 start
- BEG
, Z
- end
);
1887 Vdeactivate_mark
= Qt
;
1890 /* These macros work with an argument named `preserve_ptr'
1891 and a local variable named `preserve_marker'. */
1893 #define PRESERVE_VALUE \
1894 if (preserve_ptr && NILP (preserve_marker)) \
1895 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
1897 #define RESTORE_VALUE \
1898 if (! NILP (preserve_marker)) \
1900 *preserve_ptr = marker_position (preserve_marker); \
1901 unchain_marker (XMARKER (preserve_marker)); \
1904 #define PRESERVE_START_END \
1905 if (NILP (start_marker)) \
1906 start_marker = Fcopy_marker (start, Qnil); \
1907 if (NILP (end_marker)) \
1908 end_marker = Fcopy_marker (end, Qnil);
1910 #define FETCH_START \
1911 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
1914 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
1916 /* Set a variable to nil if an error occurred.
1917 Don't change the variable if there was no error.
1918 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
1919 VARIABLE is the variable to maybe set to nil.
1920 NO-ERROR-FLAG is nil if there was an error,
1921 anything else meaning no error (so this function does nothing). */
1923 reset_var_on_error (Lisp_Object val
)
1925 if (NILP (XCDR (val
)))
1926 Fset (XCAR (val
), Qnil
);
1930 /* Signal a change to the buffer immediately before it happens.
1931 START_INT and END_INT are the bounds of the text to be changed.
1933 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1934 by holding its value temporarily in a marker. */
1937 signal_before_change (ptrdiff_t start_int
, ptrdiff_t end_int
,
1938 ptrdiff_t *preserve_ptr
)
1940 Lisp_Object start
, end
;
1941 Lisp_Object start_marker
, end_marker
;
1942 Lisp_Object preserve_marker
;
1943 struct gcpro gcpro1
, gcpro2
, gcpro3
;
1944 ptrdiff_t count
= SPECPDL_INDEX ();
1946 if (inhibit_modification_hooks
)
1949 start
= make_number (start_int
);
1950 end
= make_number (end_int
);
1951 preserve_marker
= Qnil
;
1952 start_marker
= Qnil
;
1954 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
1956 specbind (Qinhibit_modification_hooks
, Qt
);
1958 /* If buffer is unmodified, run a special hook for that case. The
1959 check for Vfirst_change_hook is just a minor optimization. */
1960 if (SAVE_MODIFF
>= MODIFF
1961 && !NILP (Vfirst_change_hook
))
1965 Frun_hooks (1, &Qfirst_change_hook
);
1968 /* Now run the before-change-functions if any. */
1969 if (!NILP (Vbefore_change_functions
))
1971 Lisp_Object args
[3];
1972 Lisp_Object rvoe_arg
= Fcons (Qbefore_change_functions
, Qnil
);
1977 /* Mark before-change-functions to be reset to nil in case of error. */
1978 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
1980 /* Actually run the hook functions. */
1981 args
[0] = Qbefore_change_functions
;
1982 args
[1] = FETCH_START
;
1983 args
[2] = FETCH_END
;
1984 Frun_hook_with_args (3, args
);
1986 /* There was no error: unarm the reset_on_error. */
1987 XSETCDR (rvoe_arg
, Qt
);
1990 if (buffer_has_overlays ())
1993 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
1994 FETCH_START
, FETCH_END
, Qnil
);
1997 if (! NILP (start_marker
))
1998 free_marker (start_marker
);
1999 if (! NILP (end_marker
))
2000 free_marker (end_marker
);
2004 unbind_to (count
, Qnil
);
2007 /* Signal a change immediately after it happens.
2008 CHARPOS is the character position of the start of the changed text.
2009 LENDEL is the number of characters of the text before the change.
2010 (Not the whole buffer; just the part that was changed.)
2011 LENINS is the number of characters in that part of the text
2012 after the change. */
2015 signal_after_change (ptrdiff_t charpos
, ptrdiff_t lendel
, ptrdiff_t lenins
)
2017 ptrdiff_t count
= SPECPDL_INDEX ();
2018 if (inhibit_modification_hooks
)
2021 /* If we are deferring calls to the after-change functions
2022 and there are no before-change functions,
2023 just record the args that we were going to use. */
2024 if (! NILP (Vcombine_after_change_calls
)
2025 && NILP (Vbefore_change_functions
)
2026 && !buffer_has_overlays ())
2030 if (!NILP (combine_after_change_list
)
2031 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2032 Fcombine_after_change_execute ();
2034 elt
= Fcons (make_number (charpos
- BEG
),
2035 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2036 Fcons (make_number (lenins
- lendel
), Qnil
)));
2037 combine_after_change_list
2038 = Fcons (elt
, combine_after_change_list
);
2039 combine_after_change_buffer
= Fcurrent_buffer ();
2044 if (!NILP (combine_after_change_list
))
2045 Fcombine_after_change_execute ();
2047 specbind (Qinhibit_modification_hooks
, Qt
);
2049 if (!NILP (Vafter_change_functions
))
2051 Lisp_Object args
[4];
2052 Lisp_Object rvoe_arg
= Fcons (Qafter_change_functions
, Qnil
);
2054 /* Mark after-change-functions to be reset to nil in case of error. */
2055 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2057 /* Actually run the hook functions. */
2058 args
[0] = Qafter_change_functions
;
2059 XSETFASTINT (args
[1], charpos
);
2060 XSETFASTINT (args
[2], charpos
+ lenins
);
2061 XSETFASTINT (args
[3], lendel
);
2062 Frun_hook_with_args (4, args
);
2064 /* There was no error: unarm the reset_on_error. */
2065 XSETCDR (rvoe_arg
, Qt
);
2068 if (buffer_has_overlays ())
2069 report_overlay_modification (make_number (charpos
),
2070 make_number (charpos
+ lenins
),
2072 make_number (charpos
),
2073 make_number (charpos
+ lenins
),
2074 make_number (lendel
));
2076 /* After an insertion, call the text properties
2077 insert-behind-hooks or insert-in-front-hooks. */
2079 report_interval_modification (make_number (charpos
),
2080 make_number (charpos
+ lenins
));
2082 unbind_to (count
, Qnil
);
2086 Fcombine_after_change_execute_1 (Lisp_Object val
)
2088 Vcombine_after_change_calls
= val
;
2092 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2093 Scombine_after_change_execute
, 0, 0, 0,
2094 doc
: /* This function is for use internally in `combine-after-change-calls'. */)
2097 ptrdiff_t count
= SPECPDL_INDEX ();
2098 ptrdiff_t beg
, end
, change
;
2099 ptrdiff_t begpos
, endpos
;
2102 if (NILP (combine_after_change_list
))
2105 /* It is rare for combine_after_change_buffer to be invalid, but
2106 possible. It can happen when combine-after-change-calls is
2107 non-nil, and insertion calls a file handler (e.g. through
2108 lock_file) which scribbles into a temp file -- cyd */
2109 if (!BUFFERP (combine_after_change_buffer
)
2110 || !BUFFER_LIVE_P (XBUFFER (combine_after_change_buffer
)))
2112 combine_after_change_list
= Qnil
;
2116 record_unwind_current_buffer ();
2118 Fset_buffer (combine_after_change_buffer
);
2120 /* # chars unchanged at beginning of buffer. */
2122 /* # chars unchanged at end of buffer. */
2124 /* Total amount of insertion (negative for deletion). */
2127 /* Scan the various individual changes,
2128 accumulating the range info in BEG, END and CHANGE. */
2129 for (tail
= combine_after_change_list
; CONSP (tail
);
2133 ptrdiff_t thisbeg
, thisend
, thischange
;
2135 /* Extract the info from the next element. */
2139 thisbeg
= XINT (XCAR (elt
));
2144 thisend
= XINT (XCAR (elt
));
2149 thischange
= XINT (XCAR (elt
));
2151 /* Merge this range into the accumulated range. */
2152 change
+= thischange
;
2159 /* Get the current start and end positions of the range
2160 that was changed. */
2164 /* We are about to handle these, so discard them. */
2165 combine_after_change_list
= Qnil
;
2167 /* Now run the after-change functions for real.
2168 Turn off the flag that defers them. */
2169 record_unwind_protect (Fcombine_after_change_execute_1
,
2170 Vcombine_after_change_calls
);
2171 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2172 update_compositions (begpos
, endpos
, CHECK_ALL
);
2174 return unbind_to (count
, Qnil
);
2178 syms_of_insdel (void)
2180 staticpro (&combine_after_change_list
);
2181 staticpro (&combine_after_change_buffer
);
2182 combine_after_change_list
= Qnil
;
2183 combine_after_change_buffer
= Qnil
;
2185 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls
,
2186 doc
: /* Used internally by the `combine-after-change-calls' macro. */);
2187 Vcombine_after_change_calls
= Qnil
;
2189 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks
,
2190 doc
: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2191 This affects `before-change-functions' and `after-change-functions',
2192 as well as hooks attached to text properties and overlays. */);
2193 inhibit_modification_hooks
= 0;
2194 DEFSYM (Qinhibit_modification_hooks
, "inhibit-modification-hooks");
2196 defsubr (&Scombine_after_change_execute
);