1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985-1986, 1993-1995, 1997-2014 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 byte position BYTEPOS, which is also char position CHARPOS.
88 Note that this can quit! */
91 move_gap_both (ptrdiff_t charpos
, ptrdiff_t bytepos
)
93 eassert (charpos
== BYTE_TO_CHAR (bytepos
)
94 && bytepos
== CHAR_TO_BYTE (charpos
));
95 if (bytepos
< GPT_BYTE
)
96 gap_left (charpos
, bytepos
, 0);
97 else if (bytepos
> GPT_BYTE
)
98 gap_right (charpos
, bytepos
);
101 /* Move the gap to a position less than the current GPT.
102 BYTEPOS describes the new position as a byte position,
103 and CHARPOS is the corresponding char position.
104 If NEWGAP, then don't update beg_unchanged and end_unchanged. */
107 gap_left (ptrdiff_t charpos
, ptrdiff_t bytepos
, bool newgap
)
109 unsigned char *to
, *from
;
114 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
121 /* Now copy the characters. To move the gap down,
122 copy characters up. */
126 /* I gets number of characters left to copy. */
127 i
= new_s1
- bytepos
;
130 /* If a quit is requested, stop copying now.
131 Change BYTEPOS to be where we have actually moved the gap to. */
135 charpos
= BYTE_TO_CHAR (bytepos
);
138 /* Move at most 32000 chars before checking again for a quit. */
143 memmove (to
, from
, i
);
146 /* Adjust buffer data structure, to put the gap at BYTEPOS.
147 BYTEPOS is where the loop above stopped, which may be what
148 was specified or may be where a quit was detected. */
151 eassert (charpos
<= bytepos
);
152 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
156 /* Move the gap to a position greater than the current GPT.
157 BYTEPOS describes the new position as a byte position,
158 and CHARPOS is the corresponding char position. */
161 gap_right (ptrdiff_t charpos
, ptrdiff_t bytepos
)
163 register unsigned char *to
, *from
;
164 register ptrdiff_t i
;
167 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
174 /* Now copy the characters. To move the gap up,
175 copy characters down. */
179 /* I gets number of characters left to copy. */
180 i
= bytepos
- new_s1
;
183 /* If a quit is requested, stop copying now.
184 Change BYTEPOS to be where we have actually moved the gap to. */
188 charpos
= BYTE_TO_CHAR (bytepos
);
191 /* Move at most 32000 chars before checking again for a quit. */
195 memmove (to
, from
, i
);
201 eassert (charpos
<= bytepos
);
202 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
206 /* Adjust all markers for a deletion
207 whose range in bytes is FROM_BYTE to TO_BYTE.
208 The range in charpos is FROM to TO.
210 This function assumes that the gap is adjacent to
211 or inside of the range being deleted. */
214 adjust_markers_for_delete (ptrdiff_t from
, ptrdiff_t from_byte
,
215 ptrdiff_t to
, ptrdiff_t to_byte
)
218 register struct Lisp_Marker
*m
;
219 register ptrdiff_t charpos
;
221 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
223 charpos
= m
->charpos
;
224 eassert (charpos
<= Z
);
226 /* If the marker is after the deletion,
227 relocate by number of chars / bytes deleted. */
230 m
->charpos
-= to
- from
;
231 m
->bytepos
-= to_byte
- from_byte
;
233 /* Here's the case where a marker is inside text being deleted. */
234 else if (charpos
> from
)
237 m
->bytepos
= from_byte
;
243 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
244 to TO / TO_BYTE. We have to relocate the charpos of every marker
245 that points after the insertion (but not their bytepos).
247 When a marker points at the insertion point,
248 we advance it if either its insertion-type is t
249 or BEFORE_MARKERS is true. */
252 adjust_markers_for_insert (ptrdiff_t from
, ptrdiff_t from_byte
,
253 ptrdiff_t to
, ptrdiff_t to_byte
, bool before_markers
)
255 struct Lisp_Marker
*m
;
257 ptrdiff_t nchars
= to
- from
;
258 ptrdiff_t nbytes
= to_byte
- from_byte
;
260 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
262 eassert (m
->bytepos
>= m
->charpos
263 && m
->bytepos
- m
->charpos
<= Z_BYTE
- Z
);
265 if (m
->bytepos
== from_byte
)
267 if (m
->insertion_type
|| before_markers
)
269 m
->bytepos
= to_byte
;
271 if (m
->insertion_type
)
275 else if (m
->bytepos
> from_byte
)
277 m
->bytepos
+= nbytes
;
278 m
->charpos
+= nchars
;
282 /* Adjusting only markers whose insertion-type is t may result in
283 - disordered start and end in overlays, and
284 - disordered overlays in the slot `overlays_before' of current_buffer. */
287 fix_start_end_in_overlays (from
, to
);
288 fix_overlays_before (current_buffer
, from
, to
);
292 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
294 This is used only when the value of point changes due to an insert
295 or delete; it does not represent a conceptual change in point as a
296 marker. In particular, point is not crossing any interval
297 boundaries, so there's no need to use the usual SET_PT macro. In
298 fact it would be incorrect to do so, because either the old or the
299 new value of point is out of sync with the current set of
303 adjust_point (ptrdiff_t nchars
, ptrdiff_t nbytes
)
305 SET_BUF_PT_BOTH (current_buffer
, PT
+ nchars
, PT_BYTE
+ nbytes
);
306 /* In a single-byte buffer, the two positions must be equal. */
307 eassert (PT_BYTE
>= PT
&& PT_BYTE
- PT
<= ZV_BYTE
- ZV
);
310 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
311 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
312 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
316 adjust_markers_for_replace (ptrdiff_t from
, ptrdiff_t from_byte
,
317 ptrdiff_t old_chars
, ptrdiff_t old_bytes
,
318 ptrdiff_t new_chars
, ptrdiff_t new_bytes
)
320 register struct Lisp_Marker
*m
;
321 ptrdiff_t prev_to_byte
= from_byte
+ old_bytes
;
322 ptrdiff_t diff_chars
= new_chars
- old_chars
;
323 ptrdiff_t diff_bytes
= new_bytes
- old_bytes
;
325 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
327 if (m
->bytepos
>= prev_to_byte
)
329 m
->charpos
+= diff_chars
;
330 m
->bytepos
+= diff_bytes
;
332 else if (m
->bytepos
> from_byte
)
335 m
->bytepos
= from_byte
;
344 buffer_overflow (void)
346 error ("Maximum buffer size exceeded");
349 /* Make the gap NBYTES_ADDED bytes longer. */
352 make_gap_larger (ptrdiff_t nbytes_added
)
355 ptrdiff_t real_gap_loc
;
356 ptrdiff_t real_gap_loc_byte
;
357 ptrdiff_t old_gap_size
;
358 ptrdiff_t current_size
= Z_BYTE
- BEG_BYTE
+ GAP_SIZE
;
360 if (BUF_BYTES_MAX
- current_size
< nbytes_added
)
363 /* If we have to get more space, get enough to last a while;
364 but do not exceed the maximum buffer size. */
365 nbytes_added
= min (nbytes_added
+ GAP_BYTES_DFL
,
366 BUF_BYTES_MAX
- current_size
);
368 enlarge_buffer_text (current_buffer
, nbytes_added
);
370 /* Prevent quitting in move_gap. */
375 real_gap_loc_byte
= GPT_BYTE
;
376 old_gap_size
= GAP_SIZE
;
378 /* Call the newly allocated space a gap at the end of the whole space. */
380 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
381 GAP_SIZE
= nbytes_added
;
383 /* Move the new gap down to be consecutive with the end of the old one. */
384 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
386 /* Now combine the two into one large gap. */
387 GAP_SIZE
+= old_gap_size
;
389 GPT_BYTE
= real_gap_loc_byte
;
397 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
399 /* Make the gap NBYTES_REMOVED bytes shorter. */
402 make_gap_smaller (ptrdiff_t nbytes_removed
)
405 ptrdiff_t real_gap_loc
;
406 ptrdiff_t real_gap_loc_byte
;
408 ptrdiff_t real_Z_byte
;
409 ptrdiff_t real_beg_unchanged
;
410 ptrdiff_t new_gap_size
;
412 /* Make sure the gap is at least GAP_BYTES_MIN bytes. */
413 if (GAP_SIZE
- nbytes_removed
< GAP_BYTES_MIN
)
414 nbytes_removed
= GAP_SIZE
- GAP_BYTES_MIN
;
416 /* Prevent quitting in move_gap. */
421 real_gap_loc_byte
= GPT_BYTE
;
422 new_gap_size
= GAP_SIZE
- nbytes_removed
;
424 real_Z_byte
= Z_BYTE
;
425 real_beg_unchanged
= BEG_UNCHANGED
;
427 /* Pretend that the last unwanted part of the gap is the entire gap,
428 and that the first desired part of the gap is part of the buffer
430 memset (GPT_ADDR
, 0, new_gap_size
);
432 GPT_BYTE
+= new_gap_size
;
434 Z_BYTE
+= new_gap_size
;
435 GAP_SIZE
= nbytes_removed
;
437 /* Move the unwanted pretend gap to the end of the buffer. */
438 gap_right (Z
, Z_BYTE
);
440 enlarge_buffer_text (current_buffer
, -nbytes_removed
);
442 /* Now restore the desired gap. */
443 GAP_SIZE
= new_gap_size
;
445 GPT_BYTE
= real_gap_loc_byte
;
447 Z_BYTE
= real_Z_byte
;
448 BEG_UNCHANGED
= real_beg_unchanged
;
456 #endif /* USE_MMAP_FOR_BUFFERS || REL_ALLOC || DOUG_LEA_MALLOC */
459 make_gap (ptrdiff_t nbytes_added
)
461 if (nbytes_added
>= 0)
462 make_gap_larger (nbytes_added
);
463 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
465 make_gap_smaller (-nbytes_added
);
469 /* Add NBYTES to B's gap. It's enough to temporarily
470 fake current_buffer and avoid real switch to B. */
473 make_gap_1 (struct buffer
*b
, ptrdiff_t nbytes
)
475 struct buffer
*oldb
= current_buffer
;
479 current_buffer
= oldb
;
482 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
483 FROM_MULTIBYTE says whether the incoming text is multibyte.
484 TO_MULTIBYTE says whether to store the text as multibyte.
485 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
487 Return the number of bytes stored at TO_ADDR. */
490 copy_text (const unsigned char *from_addr
, unsigned char *to_addr
,
491 ptrdiff_t nbytes
, bool from_multibyte
, bool to_multibyte
)
493 if (from_multibyte
== to_multibyte
)
495 memcpy (to_addr
, from_addr
, nbytes
);
498 else if (from_multibyte
)
500 ptrdiff_t nchars
= 0;
501 ptrdiff_t bytes_left
= nbytes
;
503 while (bytes_left
> 0)
506 c
= STRING_CHAR_AND_LENGTH (from_addr
, thislen
);
507 if (! ASCII_CHAR_P (c
))
510 from_addr
+= thislen
;
511 bytes_left
-= thislen
;
518 unsigned char *initial_to_addr
= to_addr
;
520 /* Convert single-byte to multibyte. */
523 int c
= *from_addr
++;
525 if (!ASCII_CHAR_P (c
))
527 c
= BYTE8_TO_CHAR (c
);
528 to_addr
+= CHAR_STRING (c
, to_addr
);
532 /* Special case for speed. */
533 *to_addr
++ = c
, nbytes
--;
535 return to_addr
- initial_to_addr
;
539 /* Insert a string of specified length before point.
540 This function judges multibyteness based on
541 enable_multibyte_characters in the current buffer;
542 it never converts between single-byte and multibyte.
544 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
545 prepare_to_modify_buffer could relocate the text. */
548 insert (const char *string
, ptrdiff_t nbytes
)
552 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
553 insert_1_both (string
, len
, nbytes
, 0, 1, 0);
555 signal_after_change (opoint
, 0, len
);
556 update_compositions (opoint
, PT
, CHECK_BORDER
);
560 /* Likewise, but inherit text properties from neighboring characters. */
563 insert_and_inherit (const char *string
, ptrdiff_t nbytes
)
567 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
568 insert_1_both (string
, len
, nbytes
, 1, 1, 0);
570 signal_after_change (opoint
, 0, len
);
571 update_compositions (opoint
, PT
, CHECK_BORDER
);
575 /* Insert the character C before point. Do not inherit text properties. */
580 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
583 if (! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
584 len
= CHAR_STRING (c
, str
);
591 insert ((char *) str
, len
);
594 /* Insert the null-terminated string S before point. */
597 insert_string (const char *s
)
599 insert (s
, strlen (s
));
602 /* Like `insert' except that all markers pointing at the place where
603 the insertion happens are adjusted to point after it.
604 Don't use this function to insert part of a Lisp string,
605 since gc could happen and relocate it. */
608 insert_before_markers (const char *string
, ptrdiff_t nbytes
)
612 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
613 insert_1_both (string
, len
, nbytes
, 0, 1, 1);
615 signal_after_change (opoint
, 0, len
);
616 update_compositions (opoint
, PT
, CHECK_BORDER
);
620 /* Likewise, but inherit text properties from neighboring characters. */
623 insert_before_markers_and_inherit (const char *string
,
628 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
629 insert_1_both (string
, len
, nbytes
, 1, 1, 1);
631 signal_after_change (opoint
, 0, len
);
632 update_compositions (opoint
, PT
, CHECK_BORDER
);
636 #ifdef BYTE_COMBINING_DEBUG
638 /* See if the bytes before POS/POS_BYTE combine with bytes
639 at the start of STRING to form a single character.
640 If so, return the number of bytes at the start of STRING
641 which combine in this way. Otherwise, return 0. */
644 count_combining_before (const unsigned char *string
, ptrdiff_t length
,
645 ptrdiff_t pos
, ptrdiff_t pos_byte
)
647 int len
, combining_bytes
;
648 const unsigned char *p
;
650 if (NILP (current_buffer
->enable_multibyte_characters
))
653 /* At first, we can exclude the following cases:
654 (1) STRING[0] can't be a following byte of multibyte sequence.
655 (2) POS is the start of the current buffer.
656 (3) A character before POS is not a multibyte character. */
657 if (length
== 0 || CHAR_HEAD_P (*string
)) /* case (1) */
659 if (pos_byte
== BEG_BYTE
) /* case (2) */
662 p
= BYTE_POS_ADDR (pos_byte
- 1);
663 while (! CHAR_HEAD_P (*p
)) p
--, len
++;
664 if (! LEADING_CODE_P (*p
)) /* case (3) */
667 combining_bytes
= BYTES_BY_CHAR_HEAD (*p
) - len
;
668 if (combining_bytes
<= 0)
669 /* The character preceding POS is, complete and no room for
670 combining bytes (combining_bytes == 0), or an independent 8-bit
671 character (combining_bytes < 0). */
674 /* We have a combination situation. Count the bytes at STRING that
677 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
680 return (combining_bytes
< p
- string
? combining_bytes
: p
- string
);
683 /* See if the bytes after POS/POS_BYTE combine with bytes
684 at the end of STRING to form a single character.
685 If so, return the number of bytes after POS/POS_BYTE
686 which combine in this way. Otherwise, return 0. */
689 count_combining_after (const unsigned char *string
,
690 ptrdiff_t length
, ptrdiff_t pos
, ptrdiff_t pos_byte
)
692 ptrdiff_t opos_byte
= pos_byte
;
697 if (NILP (current_buffer
->enable_multibyte_characters
))
700 /* At first, we can exclude the following cases:
701 (1) The last byte of STRING is an ASCII.
702 (2) POS is the last of the current buffer.
703 (3) A character at POS can't be a following byte of multibyte
705 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1])) /* case (1) */
707 if (pos_byte
== Z_BYTE
) /* case (2) */
709 bufp
= BYTE_POS_ADDR (pos_byte
);
710 if (CHAR_HEAD_P (*bufp
)) /* case (3) */
714 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
720 /* All characters in STRING are not character head. We must
721 check also preceding bytes at POS. We are sure that the gap
723 unsigned char *p
= BEG_ADDR
;
725 while (i
>= 0 && ! CHAR_HEAD_P (p
[i
]))
727 if (i
< 0 || !LEADING_CODE_P (p
[i
]))
730 bytes
= BYTES_BY_CHAR_HEAD (p
[i
]);
731 return (bytes
<= pos_byte
- 1 - i
+ length
733 : bytes
- (pos_byte
- 1 - i
+ length
));
735 if (!LEADING_CODE_P (string
[i
]))
738 bytes
= BYTES_BY_CHAR_HEAD (string
[i
]) - (length
- i
);
740 while (!CHAR_HEAD_P (*bufp
)) bufp
++, pos_byte
++;
742 return (bytes
<= pos_byte
- opos_byte
? bytes
: pos_byte
- opos_byte
);
748 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
749 starting at STRING. INHERIT non-zero means inherit the text
750 properties from neighboring characters; zero means inserted text
751 will have no text properties. PREPARE non-zero means call
752 prepare_to_modify_buffer, which checks that the region is not
753 read-only, and calls before-change-function and any modification
754 properties the text may have. BEFORE_MARKERS non-zero means adjust
755 all markers that point at the insertion place to point after it. */
758 insert_1_both (const char *string
,
759 ptrdiff_t nchars
, ptrdiff_t nbytes
,
760 bool inherit
, bool prepare
, bool before_markers
)
765 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
769 /* Do this before moving and increasing the gap,
770 because the before-change hooks might move the gap
771 or make it smaller. */
772 prepare_to_modify_buffer (PT
, PT
, NULL
);
775 move_gap_both (PT
, PT_BYTE
);
776 if (GAP_SIZE
< nbytes
)
777 make_gap (nbytes
- GAP_SIZE
);
779 #ifdef BYTE_COMBINING_DEBUG
780 if (count_combining_before (string
, nbytes
, PT
, PT_BYTE
)
781 || count_combining_after (string
, nbytes
, PT
, PT_BYTE
))
785 /* Record deletion of the surrounding text that combines with
786 the insertion. This, together with recording the insertion,
787 will add up to the right stuff in the undo list. */
788 record_insert (PT
, nchars
);
790 CHARS_MODIFF
= MODIFF
;
792 memcpy (GPT_ADDR
, string
, nbytes
);
801 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
803 eassert (GPT
<= GPT_BYTE
);
805 /* The insert may have been in the unchanged region, so check again. */
806 if (Z
- GPT
< END_UNCHANGED
)
807 END_UNCHANGED
= Z
- GPT
;
809 adjust_overlays_for_insert (PT
, nchars
);
810 adjust_markers_for_insert (PT
, PT_BYTE
,
811 PT
+ nchars
, PT_BYTE
+ nbytes
,
814 offset_intervals (current_buffer
, PT
, nchars
);
816 if (!inherit
&& buffer_intervals (current_buffer
))
817 set_text_properties (make_number (PT
), make_number (PT
+ nchars
),
820 adjust_point (nchars
, nbytes
);
825 /* Insert the part of the text of STRING, a Lisp object assumed to be
826 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
827 starting at position POS / POS_BYTE. If the text of STRING has properties,
828 copy them into the buffer.
830 It does not work to use `insert' for this, because a GC could happen
831 before we copy the stuff into the buffer, and relocate the string
832 without insert noticing. */
835 insert_from_string (Lisp_Object string
, ptrdiff_t pos
, ptrdiff_t pos_byte
,
836 ptrdiff_t length
, ptrdiff_t length_byte
, bool inherit
)
838 ptrdiff_t opoint
= PT
;
840 if (SCHARS (string
) == 0)
843 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
845 signal_after_change (opoint
, 0, PT
- opoint
);
846 update_compositions (opoint
, PT
, CHECK_BORDER
);
849 /* Like `insert_from_string' except that all markers pointing
850 at the place where the insertion happens are adjusted to point after it. */
853 insert_from_string_before_markers (Lisp_Object string
,
854 ptrdiff_t pos
, ptrdiff_t pos_byte
,
855 ptrdiff_t length
, ptrdiff_t length_byte
,
858 ptrdiff_t opoint
= PT
;
860 if (SCHARS (string
) == 0)
863 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
865 signal_after_change (opoint
, 0, PT
- opoint
);
866 update_compositions (opoint
, PT
, CHECK_BORDER
);
869 /* Subroutine of the insertion functions above. */
872 insert_from_string_1 (Lisp_Object string
, ptrdiff_t pos
, ptrdiff_t pos_byte
,
873 ptrdiff_t nchars
, ptrdiff_t nbytes
,
874 bool inherit
, bool before_markers
)
877 ptrdiff_t outgoing_nbytes
= nbytes
;
880 /* Make OUTGOING_NBYTES describe the text
881 as it will be inserted in this buffer. */
883 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
884 outgoing_nbytes
= nchars
;
885 else if (! STRING_MULTIBYTE (string
))
887 = count_size_as_multibyte (SDATA (string
) + pos_byte
,
891 /* Do this before moving and increasing the gap,
892 because the before-change hooks might move the gap
893 or make it smaller. */
894 prepare_to_modify_buffer (PT
, PT
, NULL
);
897 move_gap_both (PT
, PT_BYTE
);
898 if (GAP_SIZE
< outgoing_nbytes
)
899 make_gap (outgoing_nbytes
- GAP_SIZE
);
902 /* Copy the string text into the buffer, perhaps converting
903 between single-byte and multibyte. */
904 copy_text (SDATA (string
) + pos_byte
, GPT_ADDR
, nbytes
,
905 STRING_MULTIBYTE (string
),
906 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
908 #ifdef BYTE_COMBINING_DEBUG
909 /* We have copied text into the gap, but we have not altered
910 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
911 to these functions and get the same results as we would
912 have got earlier on. Meanwhile, PT_ADDR does point to
913 the text that has been stored by copy_text. */
914 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
915 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
919 record_insert (PT
, nchars
);
921 CHARS_MODIFF
= MODIFF
;
923 GAP_SIZE
-= outgoing_nbytes
;
927 GPT_BYTE
+= outgoing_nbytes
;
928 ZV_BYTE
+= outgoing_nbytes
;
929 Z_BYTE
+= outgoing_nbytes
;
930 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
932 eassert (GPT
<= GPT_BYTE
);
934 /* The insert may have been in the unchanged region, so check again. */
935 if (Z
- GPT
< END_UNCHANGED
)
936 END_UNCHANGED
= Z
- GPT
;
938 adjust_overlays_for_insert (PT
, nchars
);
939 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
940 PT_BYTE
+ outgoing_nbytes
,
943 offset_intervals (current_buffer
, PT
, nchars
);
945 intervals
= string_intervals (string
);
946 /* Get the intervals for the part of the string we are inserting. */
947 if (nbytes
< SBYTES (string
))
948 intervals
= copy_intervals (intervals
, pos
, nchars
);
950 /* Insert those intervals. */
951 graft_intervals_into_buffer (intervals
, PT
, nchars
,
952 current_buffer
, inherit
);
954 adjust_point (nchars
, outgoing_nbytes
);
959 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
960 starting at GAP_END_ADDR - NBYTES (if text_at_gap_tail) and at
961 GPT_ADDR (if not text_at_gap_tail). */
964 insert_from_gap (ptrdiff_t nchars
, ptrdiff_t nbytes
, bool text_at_gap_tail
)
966 ptrdiff_t ins_charpos
= GPT
, ins_bytepos
= GPT_BYTE
;
968 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
971 /* No need to call prepare_to_modify_buffer, since this is called
972 from places that replace some region with a different text, so
973 prepare_to_modify_buffer was already called by the deletion part
975 invalidate_buffer_caches (current_buffer
, GPT
, GPT
);
976 record_insert (GPT
, nchars
);
980 if (! text_at_gap_tail
)
989 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
991 eassert (GPT
<= GPT_BYTE
);
993 adjust_overlays_for_insert (ins_charpos
, nchars
);
994 adjust_markers_for_insert (ins_charpos
, ins_bytepos
,
995 ins_charpos
+ nchars
, ins_bytepos
+ nbytes
, 0);
997 if (buffer_intervals (current_buffer
))
999 offset_intervals (current_buffer
, ins_charpos
, nchars
);
1000 graft_intervals_into_buffer (NULL
, ins_charpos
, nchars
,
1004 if (ins_charpos
< PT
)
1005 adjust_point (nchars
, nbytes
);
1010 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1011 current buffer. If the text in BUF has properties, they are absorbed
1012 into the current buffer.
1014 It does not work to use `insert' for this, because a malloc could happen
1015 and relocate BUF's text before the copy happens. */
1018 insert_from_buffer (struct buffer
*buf
,
1019 ptrdiff_t charpos
, ptrdiff_t nchars
, bool inherit
)
1021 ptrdiff_t opoint
= PT
;
1023 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1024 signal_after_change (opoint
, 0, PT
- opoint
);
1025 update_compositions (opoint
, PT
, CHECK_BORDER
);
1029 insert_from_buffer_1 (struct buffer
*buf
,
1030 ptrdiff_t from
, ptrdiff_t nchars
, bool inherit
)
1032 ptrdiff_t chunk
, chunk_expanded
;
1033 ptrdiff_t from_byte
= buf_charpos_to_bytepos (buf
, from
);
1034 ptrdiff_t to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1035 ptrdiff_t incoming_nbytes
= to_byte
- from_byte
;
1036 ptrdiff_t outgoing_nbytes
= incoming_nbytes
;
1042 /* Make OUTGOING_NBYTES describe the text
1043 as it will be inserted in this buffer. */
1045 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1046 outgoing_nbytes
= nchars
;
1047 else if (NILP (BVAR (buf
, enable_multibyte_characters
)))
1049 ptrdiff_t outgoing_before_gap
= 0;
1050 ptrdiff_t outgoing_after_gap
= 0;
1052 if (from
< BUF_GPT (buf
))
1054 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1055 if (chunk
> incoming_nbytes
)
1056 chunk
= incoming_nbytes
;
1058 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1064 if (chunk
< incoming_nbytes
)
1066 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
,
1068 incoming_nbytes
- chunk
);
1070 outgoing_nbytes
= outgoing_before_gap
+ outgoing_after_gap
;
1073 /* Do this before moving and increasing the gap,
1074 because the before-change hooks might move the gap
1075 or make it smaller. */
1076 prepare_to_modify_buffer (PT
, PT
, NULL
);
1079 move_gap_both (PT
, PT_BYTE
);
1080 if (GAP_SIZE
< outgoing_nbytes
)
1081 make_gap (outgoing_nbytes
- GAP_SIZE
);
1083 if (from
< BUF_GPT (buf
))
1085 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1086 if (chunk
> incoming_nbytes
)
1087 chunk
= incoming_nbytes
;
1088 /* Record number of output bytes, so we know where
1089 to put the output from the second copy_text. */
1091 = copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1093 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1094 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1097 chunk_expanded
= chunk
= 0;
1099 if (chunk
< incoming_nbytes
)
1100 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1101 GPT_ADDR
+ chunk_expanded
, incoming_nbytes
- chunk
,
1102 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1103 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1105 #ifdef BYTE_COMBINING_DEBUG
1106 /* We have copied text into the gap, but we have not altered
1107 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1108 to these functions and get the same results as we would
1109 have got earlier on. Meanwhile, GPT_ADDR does point to
1110 the text that has been stored by copy_text. */
1111 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1112 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1116 record_insert (PT
, nchars
);
1118 CHARS_MODIFF
= MODIFF
;
1120 GAP_SIZE
-= outgoing_nbytes
;
1124 GPT_BYTE
+= outgoing_nbytes
;
1125 ZV_BYTE
+= outgoing_nbytes
;
1126 Z_BYTE
+= outgoing_nbytes
;
1127 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1129 eassert (GPT
<= GPT_BYTE
);
1131 /* The insert may have been in the unchanged region, so check again. */
1132 if (Z
- GPT
< END_UNCHANGED
)
1133 END_UNCHANGED
= Z
- GPT
;
1135 adjust_overlays_for_insert (PT
, nchars
);
1136 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1137 PT_BYTE
+ outgoing_nbytes
,
1140 offset_intervals (current_buffer
, PT
, nchars
);
1142 /* Get the intervals for the part of the string we are inserting. */
1143 intervals
= buffer_intervals (buf
);
1144 if (nchars
< BUF_Z (buf
) - BUF_BEG (buf
))
1146 if (buf
== current_buffer
&& PT
<= from
)
1148 intervals
= copy_intervals (intervals
, from
, nchars
);
1151 /* Insert those intervals. */
1152 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1154 adjust_point (nchars
, outgoing_nbytes
);
1157 /* Record undo information and adjust markers and position keepers for
1158 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1159 chars (LEN_BYTE bytes) which resides in the gap just after
1162 PREV_TEXT nil means the new text was just inserted. */
1165 adjust_after_replace (ptrdiff_t from
, ptrdiff_t from_byte
,
1166 Lisp_Object prev_text
, ptrdiff_t len
, ptrdiff_t len_byte
)
1168 ptrdiff_t nchars_del
= 0, nbytes_del
= 0;
1170 #ifdef BYTE_COMBINING_DEBUG
1171 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1172 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1176 if (STRINGP (prev_text
))
1178 nchars_del
= SCHARS (prev_text
);
1179 nbytes_del
= SBYTES (prev_text
);
1182 /* Update various buffer positions for the new text. */
1183 GAP_SIZE
-= len_byte
;
1185 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1186 GPT
+= len
; GPT_BYTE
+= len_byte
;
1187 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1190 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1193 adjust_markers_for_insert (from
, from_byte
,
1194 from
+ len
, from_byte
+ len_byte
, 0);
1197 record_delete (from
, prev_text
, false);
1198 record_insert (from
, len
);
1200 if (len
> nchars_del
)
1201 adjust_overlays_for_insert (from
, len
- nchars_del
);
1202 else if (len
< nchars_del
)
1203 adjust_overlays_for_delete (from
, nchars_del
- len
);
1205 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1208 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1210 /* As byte combining will decrease Z, we must check this again. */
1211 if (Z
- GPT
< END_UNCHANGED
)
1212 END_UNCHANGED
= Z
- GPT
;
1217 evaporate_overlays (from
);
1219 CHARS_MODIFF
= MODIFF
;
1222 /* Record undo information, adjust markers and position keepers for an
1223 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1224 text already exists in the current buffer but character length (TO
1225 - FROM) may be incorrect, the correct length is NEWLEN. */
1228 adjust_after_insert (ptrdiff_t from
, ptrdiff_t from_byte
,
1229 ptrdiff_t to
, ptrdiff_t to_byte
, ptrdiff_t newlen
)
1231 ptrdiff_t len
= to
- from
, len_byte
= to_byte
- from_byte
;
1234 move_gap_both (to
, to_byte
);
1235 GAP_SIZE
+= len_byte
;
1236 GPT
-= len
; GPT_BYTE
-= len_byte
;
1237 ZV
-= len
; ZV_BYTE
-= len_byte
;
1238 Z
-= len
; Z_BYTE
-= len_byte
;
1239 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1242 /* Replace the text from character positions FROM to TO with NEW,
1243 If PREPARE, call prepare_to_modify_buffer.
1244 If INHERIT, the newly inserted text should inherit text properties
1245 from the surrounding non-deleted text. */
1247 /* Note that this does not yet handle markers quite right.
1248 Also it needs to record a single undo-entry that does a replacement
1249 rather than a separate delete and insert.
1250 That way, undo will also handle markers properly.
1252 But if MARKERS is 0, don't relocate markers. */
1255 replace_range (ptrdiff_t from
, ptrdiff_t to
, Lisp_Object
new,
1256 bool prepare
, bool inherit
, bool markers
)
1258 ptrdiff_t inschars
= SCHARS (new);
1259 ptrdiff_t insbytes
= SBYTES (new);
1260 ptrdiff_t from_byte
, to_byte
;
1261 ptrdiff_t nbytes_del
, nchars_del
;
1262 struct gcpro gcpro1
;
1264 ptrdiff_t outgoing_insbytes
= insbytes
;
1265 Lisp_Object deletion
;
1274 ptrdiff_t range_length
= to
- from
;
1275 prepare_to_modify_buffer (from
, to
, &from
);
1276 to
= from
+ range_length
;
1281 /* Make args be valid. */
1287 from_byte
= CHAR_TO_BYTE (from
);
1288 to_byte
= CHAR_TO_BYTE (to
);
1290 nchars_del
= to
- from
;
1291 nbytes_del
= to_byte
- from_byte
;
1293 if (nbytes_del
<= 0 && insbytes
== 0)
1296 /* Make OUTGOING_INSBYTES describe the text
1297 as it will be inserted in this buffer. */
1299 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1300 outgoing_insbytes
= inschars
;
1301 else if (! STRING_MULTIBYTE (new))
1303 = count_size_as_multibyte (SDATA (new), insbytes
);
1307 /* Make sure the gap is somewhere in or next to what we are deleting. */
1309 gap_right (from
, from_byte
);
1311 gap_left (to
, to_byte
, 0);
1313 /* Even if we don't record for undo, we must keep the original text
1314 because we may have to recover it because of inappropriate byte
1316 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1317 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1319 GAP_SIZE
+= nbytes_del
;
1322 ZV_BYTE
-= nbytes_del
;
1323 Z_BYTE
-= nbytes_del
;
1325 GPT_BYTE
= from_byte
;
1326 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1328 eassert (GPT
<= GPT_BYTE
);
1330 if (GPT
- BEG
< BEG_UNCHANGED
)
1331 BEG_UNCHANGED
= GPT
- BEG
;
1332 if (Z
- GPT
< END_UNCHANGED
)
1333 END_UNCHANGED
= Z
- GPT
;
1335 if (GAP_SIZE
< outgoing_insbytes
)
1336 make_gap (outgoing_insbytes
- GAP_SIZE
);
1338 /* Copy the string text into the buffer, perhaps converting
1339 between single-byte and multibyte. */
1340 copy_text (SDATA (new), GPT_ADDR
, insbytes
,
1341 STRING_MULTIBYTE (new),
1342 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1344 #ifdef BYTE_COMBINING_DEBUG
1345 /* We have copied text into the gap, but we have not marked
1346 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1347 here, for both the previous text and the following text.
1348 Meanwhile, GPT_ADDR does point to
1349 the text that has been stored by copy_text. */
1350 if (count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
)
1351 || count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
))
1355 /* Record the insertion first, so that when we undo,
1356 the deletion will be undone first. Thus, undo
1357 will insert before deleting, and thus will keep
1358 the markers before and after this text separate. */
1359 if (!NILP (deletion
))
1361 record_insert (from
+ SCHARS (deletion
), inschars
);
1362 record_delete (from
, deletion
, false);
1365 GAP_SIZE
-= outgoing_insbytes
;
1369 GPT_BYTE
+= outgoing_insbytes
;
1370 ZV_BYTE
+= outgoing_insbytes
;
1371 Z_BYTE
+= outgoing_insbytes
;
1372 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1374 eassert (GPT
<= GPT_BYTE
);
1376 /* Adjust markers for the deletion and the insertion. */
1378 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1379 inschars
, outgoing_insbytes
);
1381 /* Adjust the overlay center as needed. This must be done after
1382 adjusting the markers that bound the overlays. */
1383 adjust_overlays_for_delete (from
, nchars_del
);
1384 adjust_overlays_for_insert (from
, inschars
);
1386 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1388 /* Get the intervals for the part of the string we are inserting--
1389 not including the combined-before bytes. */
1390 intervals
= string_intervals (new);
1391 /* Insert those intervals. */
1392 graft_intervals_into_buffer (intervals
, from
, inschars
,
1393 current_buffer
, inherit
);
1395 /* Relocate point as if it were a marker. */
1397 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1398 (from_byte
+ outgoing_insbytes
1399 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1401 if (outgoing_insbytes
== 0)
1402 evaporate_overlays (from
);
1407 CHARS_MODIFF
= MODIFF
;
1410 signal_after_change (from
, nchars_del
, GPT
- from
);
1411 update_compositions (from
, GPT
, CHECK_BORDER
);
1414 /* Replace the text from character positions FROM to TO with
1415 the text in INS of length INSCHARS.
1416 Keep the text properties that applied to the old characters
1417 (extending them to all the new chars if there are more new chars).
1419 Note that this does not yet handle markers quite right.
1421 If MARKERS, relocate markers.
1423 Unlike most functions at this level, never call
1424 prepare_to_modify_buffer and never call signal_after_change. */
1427 replace_range_2 (ptrdiff_t from
, ptrdiff_t from_byte
,
1428 ptrdiff_t to
, ptrdiff_t to_byte
,
1429 const char *ins
, ptrdiff_t inschars
, ptrdiff_t insbytes
,
1432 ptrdiff_t nbytes_del
, nchars_del
;
1436 nchars_del
= to
- from
;
1437 nbytes_del
= to_byte
- from_byte
;
1439 if (nbytes_del
<= 0 && insbytes
== 0)
1442 /* Make sure the gap is somewhere in or next to what we are deleting. */
1444 gap_right (from
, from_byte
);
1446 gap_left (to
, to_byte
, 0);
1448 GAP_SIZE
+= nbytes_del
;
1451 ZV_BYTE
-= nbytes_del
;
1452 Z_BYTE
-= nbytes_del
;
1454 GPT_BYTE
= from_byte
;
1455 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1457 eassert (GPT
<= GPT_BYTE
);
1459 if (GPT
- BEG
< BEG_UNCHANGED
)
1460 BEG_UNCHANGED
= GPT
- BEG
;
1461 if (Z
- GPT
< END_UNCHANGED
)
1462 END_UNCHANGED
= Z
- GPT
;
1464 if (GAP_SIZE
< insbytes
)
1465 make_gap (insbytes
- GAP_SIZE
);
1467 /* Copy the replacement text into the buffer. */
1468 memcpy (GPT_ADDR
, ins
, insbytes
);
1470 #ifdef BYTE_COMBINING_DEBUG
1471 /* We have copied text into the gap, but we have not marked
1472 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1473 here, for both the previous text and the following text.
1474 Meanwhile, GPT_ADDR does point to
1475 the text that has been stored by copy_text. */
1476 if (count_combining_before (GPT_ADDR
, insbytes
, from
, from_byte
)
1477 || count_combining_after (GPT_ADDR
, insbytes
, from
, from_byte
))
1481 GAP_SIZE
-= insbytes
;
1485 GPT_BYTE
+= insbytes
;
1486 ZV_BYTE
+= insbytes
;
1488 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1490 eassert (GPT
<= GPT_BYTE
);
1492 /* Adjust markers for the deletion and the insertion. */
1494 && ! (nchars_del
== 1 && inschars
== 1 && nbytes_del
== insbytes
))
1495 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1496 inschars
, insbytes
);
1498 /* Adjust the overlay center as needed. This must be done after
1499 adjusting the markers that bound the overlays. */
1500 if (nchars_del
!= inschars
)
1502 adjust_overlays_for_insert (from
, inschars
);
1503 adjust_overlays_for_delete (from
+ inschars
, nchars_del
);
1506 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1508 /* Relocate point as if it were a marker. */
1509 if (from
< PT
&& (nchars_del
!= inschars
|| nbytes_del
!= insbytes
))
1512 /* PT was within the deleted text. Move it to FROM. */
1513 adjust_point (from
- PT
, from_byte
- PT_BYTE
);
1515 adjust_point (inschars
- nchars_del
, insbytes
- nbytes_del
);
1519 evaporate_overlays (from
);
1524 CHARS_MODIFF
= MODIFF
;
1527 /* Delete characters in current buffer
1528 from FROM up to (but not including) TO.
1529 If TO comes before FROM, we delete nothing. */
1532 del_range (ptrdiff_t from
, ptrdiff_t to
)
1534 del_range_1 (from
, to
, 1, 0);
1537 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1538 RET_STRING says to return the deleted text. */
1541 del_range_1 (ptrdiff_t from
, ptrdiff_t to
, bool prepare
, bool ret_string
)
1543 ptrdiff_t from_byte
, to_byte
;
1544 Lisp_Object deletion
;
1545 struct gcpro gcpro1
;
1547 /* Make args be valid */
1558 ptrdiff_t range_length
= to
- from
;
1559 prepare_to_modify_buffer (from
, to
, &from
);
1560 to
= min (ZV
, from
+ range_length
);
1563 from_byte
= CHAR_TO_BYTE (from
);
1564 to_byte
= CHAR_TO_BYTE (to
);
1566 deletion
= del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
);
1568 signal_after_change (from
, to
- from
, 0);
1569 update_compositions (from
, from
, CHECK_HEAD
);
1574 /* Like del_range_1 but args are byte positions, not char positions. */
1577 del_range_byte (ptrdiff_t from_byte
, ptrdiff_t to_byte
, bool prepare
)
1581 /* Make args be valid */
1582 if (from_byte
< BEGV_BYTE
)
1583 from_byte
= BEGV_BYTE
;
1584 if (to_byte
> ZV_BYTE
)
1587 if (to_byte
<= from_byte
)
1590 from
= BYTE_TO_CHAR (from_byte
);
1591 to
= BYTE_TO_CHAR (to_byte
);
1595 ptrdiff_t old_from
= from
, old_to
= Z
- to
;
1596 ptrdiff_t range_length
= to
- from
;
1597 prepare_to_modify_buffer (from
, to
, &from
);
1598 to
= from
+ range_length
;
1600 if (old_from
!= from
)
1601 from_byte
= CHAR_TO_BYTE (from
);
1607 else if (old_to
== Z
- to
)
1608 to_byte
= CHAR_TO_BYTE (to
);
1611 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1612 signal_after_change (from
, to
- from
, 0);
1613 update_compositions (from
, from
, CHECK_HEAD
);
1616 /* Like del_range_1, but positions are specified both as charpos
1620 del_range_both (ptrdiff_t from
, ptrdiff_t from_byte
,
1621 ptrdiff_t to
, ptrdiff_t to_byte
, bool prepare
)
1623 /* Make args be valid */
1624 if (from_byte
< BEGV_BYTE
)
1625 from_byte
= BEGV_BYTE
;
1626 if (to_byte
> ZV_BYTE
)
1629 if (to_byte
<= from_byte
)
1639 ptrdiff_t old_from
= from
, old_to
= Z
- to
;
1640 ptrdiff_t range_length
= to
- from
;
1641 prepare_to_modify_buffer (from
, to
, &from
);
1642 to
= from
+ range_length
;
1644 if (old_from
!= from
)
1645 from_byte
= CHAR_TO_BYTE (from
);
1651 else if (old_to
== Z
- to
)
1652 to_byte
= CHAR_TO_BYTE (to
);
1655 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1656 signal_after_change (from
, to
- from
, 0);
1657 update_compositions (from
, from
, CHECK_HEAD
);
1660 /* Delete a range of text, specified both as character positions
1661 and byte positions. FROM and TO are character positions,
1662 while FROM_BYTE and TO_BYTE are byte positions.
1663 If RET_STRING, the deleted area is returned as a string. */
1666 del_range_2 (ptrdiff_t from
, ptrdiff_t from_byte
,
1667 ptrdiff_t to
, ptrdiff_t to_byte
, bool ret_string
)
1669 ptrdiff_t nbytes_del
, nchars_del
;
1670 Lisp_Object deletion
;
1674 nchars_del
= to
- from
;
1675 nbytes_del
= to_byte
- from_byte
;
1677 /* Make sure the gap is somewhere in or next to what we are deleting. */
1679 gap_right (from
, from_byte
);
1681 gap_left (to
, to_byte
, 0);
1683 #ifdef BYTE_COMBINING_DEBUG
1684 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
1685 Z_BYTE
- to_byte
, from
, from_byte
))
1689 if (ret_string
|| ! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1690 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1694 /* Record marker adjustments, and text deletion into undo
1696 record_delete (from
, deletion
, true);
1698 /* Relocate all markers pointing into the new, larger gap to point
1699 at the end of the text before the gap. */
1700 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1703 CHARS_MODIFF
= MODIFF
;
1705 /* Relocate point as if it were a marker. */
1707 adjust_point (from
- (PT
< to
? PT
: to
),
1708 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
1710 offset_intervals (current_buffer
, from
, - nchars_del
);
1712 /* Adjust the overlay center as needed. This must be done after
1713 adjusting the markers that bound the overlays. */
1714 adjust_overlays_for_delete (from
, nchars_del
);
1716 GAP_SIZE
+= nbytes_del
;
1717 ZV_BYTE
-= nbytes_del
;
1718 Z_BYTE
-= nbytes_del
;
1722 GPT_BYTE
= from_byte
;
1723 if (GAP_SIZE
> 0 && !current_buffer
->text
->inhibit_shrinking
)
1724 /* Put an anchor, unless called from decode_coding_object which
1725 needs to access the previous gap contents. */
1728 eassert (GPT
<= GPT_BYTE
);
1730 if (GPT
- BEG
< BEG_UNCHANGED
)
1731 BEG_UNCHANGED
= GPT
- BEG
;
1732 if (Z
- GPT
< END_UNCHANGED
)
1733 END_UNCHANGED
= Z
- GPT
;
1737 evaporate_overlays (from
);
1742 /* Call this if you're about to change the text of current buffer
1743 from character positions START to END. This checks the read-only
1744 properties of the region, calls the necessary modification hooks,
1745 and warns the next redisplay that it should pay attention to that
1749 modify_text (ptrdiff_t start
, ptrdiff_t end
)
1751 prepare_to_modify_buffer (start
, end
, NULL
);
1753 BUF_COMPUTE_UNCHANGED (current_buffer
, start
- 1, end
);
1754 if (MODIFF
<= SAVE_MODIFF
)
1755 record_first_change ();
1757 CHARS_MODIFF
= MODIFF
;
1759 bset_point_before_scroll (current_buffer
, Qnil
);
1762 Lisp_Object Qregion_extract_function
;
1764 /* Check that it is okay to modify the buffer between START and END,
1765 which are char positions.
1767 Run the before-change-function, if any. If intervals are in use,
1768 verify that the text to be modified is not read-only, and call
1769 any modification properties the text may have.
1771 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1772 by holding its value temporarily in a marker. */
1775 prepare_to_modify_buffer_1 (ptrdiff_t start
, ptrdiff_t end
,
1776 ptrdiff_t *preserve_ptr
)
1778 struct buffer
*base_buffer
;
1780 if (!NILP (BVAR (current_buffer
, read_only
)))
1781 Fbarf_if_buffer_read_only ();
1783 bset_redisplay (current_buffer
);
1785 if (buffer_intervals (current_buffer
))
1789 Lisp_Object preserve_marker
;
1790 struct gcpro gcpro1
;
1791 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
1792 GCPRO1 (preserve_marker
);
1793 verify_interval_modification (current_buffer
, start
, end
);
1794 *preserve_ptr
= marker_position (preserve_marker
);
1795 unchain_marker (XMARKER (preserve_marker
));
1799 verify_interval_modification (current_buffer
, start
, end
);
1802 /* For indirect buffers, use the base buffer to check clashes. */
1803 if (current_buffer
->base_buffer
!= 0)
1804 base_buffer
= current_buffer
->base_buffer
;
1806 base_buffer
= current_buffer
;
1808 #ifdef CLASH_DETECTION
1809 if (!NILP (BVAR (base_buffer
, file_truename
))
1810 /* Make binding buffer-file-name to nil effective. */
1811 && !NILP (BVAR (base_buffer
, filename
))
1812 && SAVE_MODIFF
>= MODIFF
)
1813 lock_file (BVAR (base_buffer
, file_truename
));
1815 /* At least warn if this file has changed on disk since it was visited. */
1816 if (!NILP (BVAR (base_buffer
, filename
))
1817 && SAVE_MODIFF
>= MODIFF
1818 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
1819 && !NILP (Ffile_exists_p (BVAR (base_buffer
, filename
))))
1820 call1 (intern ("ask-user-about-supersession-threat"),
1821 BVAR (base_buffer
,filename
));
1822 #endif /* not CLASH_DETECTION */
1824 /* If `select-active-regions' is non-nil, save the region text. */
1825 /* FIXME: Move this to Elisp (via before-change-functions). */
1826 if (!NILP (BVAR (current_buffer
, mark_active
))
1827 && !inhibit_modification_hooks
1828 && XMARKER (BVAR (current_buffer
, mark
))->buffer
1829 && NILP (Vsaved_region_selection
)
1830 && (EQ (Vselect_active_regions
, Qonly
)
1831 ? EQ (CAR_SAFE (Vtransient_mark_mode
), Qonly
)
1832 : (!NILP (Vselect_active_regions
)
1833 && !NILP (Vtransient_mark_mode
))))
1834 Vsaved_region_selection
1835 = call1 (Fsymbol_value (Qregion_extract_function
), Qnil
);
1837 signal_before_change (start
, end
, preserve_ptr
);
1838 Vdeactivate_mark
= Qt
;
1841 /* Like above, but called when we know that the buffer text
1842 will be modified and region caches should be invalidated. */
1845 prepare_to_modify_buffer (ptrdiff_t start
, ptrdiff_t end
,
1846 ptrdiff_t *preserve_ptr
)
1848 prepare_to_modify_buffer_1 (start
, end
, preserve_ptr
);
1849 invalidate_buffer_caches (current_buffer
, start
, end
);
1852 /* Invalidate the caches maintained by the buffer BUF, if any, for the
1853 region between buffer positions START and END. */
1855 invalidate_buffer_caches (struct buffer
*buf
, ptrdiff_t start
, ptrdiff_t end
)
1857 /* Indirect buffers usually have their caches set to NULL, but we
1858 need to consider the caches of their base buffer. */
1859 if (buf
->base_buffer
)
1860 buf
= buf
->base_buffer
;
1861 if (buf
->newline_cache
)
1862 invalidate_region_cache (buf
,
1864 start
- BUF_BEG (buf
), BUF_Z (buf
) - end
);
1865 if (buf
->width_run_cache
)
1866 invalidate_region_cache (buf
,
1867 buf
->width_run_cache
,
1868 start
- BUF_BEG (buf
), BUF_Z (buf
) - end
);
1869 if (buf
->bidi_paragraph_cache
)
1870 invalidate_region_cache (buf
,
1871 buf
->bidi_paragraph_cache
,
1872 start
- BUF_BEG (buf
), BUF_Z (buf
) - end
);
1875 /* These macros work with an argument named `preserve_ptr'
1876 and a local variable named `preserve_marker'. */
1878 #define PRESERVE_VALUE \
1879 if (preserve_ptr && NILP (preserve_marker)) \
1880 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
1882 #define RESTORE_VALUE \
1883 if (! NILP (preserve_marker)) \
1885 *preserve_ptr = marker_position (preserve_marker); \
1886 unchain_marker (XMARKER (preserve_marker)); \
1889 #define PRESERVE_START_END \
1890 if (NILP (start_marker)) \
1891 start_marker = Fcopy_marker (start, Qnil); \
1892 if (NILP (end_marker)) \
1893 end_marker = Fcopy_marker (end, Qnil);
1895 #define FETCH_START \
1896 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
1899 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
1901 /* Set a variable to nil if an error occurred.
1902 Don't change the variable if there was no error.
1903 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
1904 VARIABLE is the variable to maybe set to nil.
1905 NO-ERROR-FLAG is nil if there was an error,
1906 anything else meaning no error (so this function does nothing). */
1909 Lisp_Object
*location
;
1914 reset_var_on_error (void *ptr
)
1916 struct rvoe_arg
*p
= ptr
;
1918 *p
->location
= Qnil
;
1921 /* Signal a change to the buffer immediately before it happens.
1922 START_INT and END_INT are the bounds of the text to be changed.
1924 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1925 by holding its value temporarily in a marker. */
1928 signal_before_change (ptrdiff_t start_int
, ptrdiff_t end_int
,
1929 ptrdiff_t *preserve_ptr
)
1931 Lisp_Object start
, end
;
1932 Lisp_Object start_marker
, end_marker
;
1933 Lisp_Object preserve_marker
;
1934 struct gcpro gcpro1
, gcpro2
, gcpro3
;
1935 ptrdiff_t count
= SPECPDL_INDEX ();
1936 struct rvoe_arg rvoe_arg
;
1938 if (inhibit_modification_hooks
)
1941 start
= make_number (start_int
);
1942 end
= make_number (end_int
);
1943 preserve_marker
= Qnil
;
1944 start_marker
= Qnil
;
1946 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
1948 specbind (Qinhibit_modification_hooks
, Qt
);
1950 /* If buffer is unmodified, run a special hook for that case. The
1951 check for Vfirst_change_hook is just a minor optimization. */
1952 if (SAVE_MODIFF
>= MODIFF
1953 && !NILP (Vfirst_change_hook
))
1957 Frun_hooks (1, &Qfirst_change_hook
);
1960 /* Now run the before-change-functions if any. */
1961 if (!NILP (Vbefore_change_functions
))
1963 Lisp_Object args
[3];
1964 rvoe_arg
.location
= &Vbefore_change_functions
;
1965 rvoe_arg
.errorp
= 1;
1970 /* Mark before-change-functions to be reset to nil in case of error. */
1971 record_unwind_protect_ptr (reset_var_on_error
, &rvoe_arg
);
1973 /* Actually run the hook functions. */
1974 args
[0] = Qbefore_change_functions
;
1975 args
[1] = FETCH_START
;
1976 args
[2] = FETCH_END
;
1977 Frun_hook_with_args (3, args
);
1979 /* There was no error: unarm the reset_on_error. */
1980 rvoe_arg
.errorp
= 0;
1983 if (buffer_has_overlays ())
1986 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
1987 FETCH_START
, FETCH_END
, Qnil
);
1990 if (! NILP (start_marker
))
1991 free_marker (start_marker
);
1992 if (! NILP (end_marker
))
1993 free_marker (end_marker
);
1997 unbind_to (count
, Qnil
);
2000 /* Signal a change immediately after it happens.
2001 CHARPOS is the character position of the start of the changed text.
2002 LENDEL is the number of characters of the text before the change.
2003 (Not the whole buffer; just the part that was changed.)
2004 LENINS is the number of characters in that part of the text
2005 after the change. */
2008 signal_after_change (ptrdiff_t charpos
, ptrdiff_t lendel
, ptrdiff_t lenins
)
2010 ptrdiff_t count
= SPECPDL_INDEX ();
2011 struct rvoe_arg rvoe_arg
;
2013 if (inhibit_modification_hooks
)
2016 /* If we are deferring calls to the after-change functions
2017 and there are no before-change functions,
2018 just record the args that we were going to use. */
2019 if (! NILP (Vcombine_after_change_calls
)
2020 && NILP (Vbefore_change_functions
)
2021 && !buffer_has_overlays ())
2025 if (!NILP (combine_after_change_list
)
2026 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2027 Fcombine_after_change_execute ();
2029 elt
= list3i (charpos
- BEG
, Z
- (charpos
- lendel
+ lenins
),
2031 combine_after_change_list
2032 = Fcons (elt
, combine_after_change_list
);
2033 combine_after_change_buffer
= Fcurrent_buffer ();
2038 if (!NILP (combine_after_change_list
))
2039 Fcombine_after_change_execute ();
2041 specbind (Qinhibit_modification_hooks
, Qt
);
2043 if (!NILP (Vafter_change_functions
))
2045 Lisp_Object args
[4];
2046 rvoe_arg
.location
= &Vafter_change_functions
;
2047 rvoe_arg
.errorp
= 1;
2049 /* Mark after-change-functions to be reset to nil in case of error. */
2050 record_unwind_protect_ptr (reset_var_on_error
, &rvoe_arg
);
2052 /* Actually run the hook functions. */
2053 args
[0] = Qafter_change_functions
;
2054 XSETFASTINT (args
[1], charpos
);
2055 XSETFASTINT (args
[2], charpos
+ lenins
);
2056 XSETFASTINT (args
[3], lendel
);
2057 Frun_hook_with_args (4, args
);
2059 /* There was no error: unarm the reset_on_error. */
2060 rvoe_arg
.errorp
= 0;
2063 if (buffer_has_overlays ())
2064 report_overlay_modification (make_number (charpos
),
2065 make_number (charpos
+ lenins
),
2067 make_number (charpos
),
2068 make_number (charpos
+ lenins
),
2069 make_number (lendel
));
2071 /* After an insertion, call the text properties
2072 insert-behind-hooks or insert-in-front-hooks. */
2074 report_interval_modification (make_number (charpos
),
2075 make_number (charpos
+ lenins
));
2077 unbind_to (count
, Qnil
);
2081 Fcombine_after_change_execute_1 (Lisp_Object val
)
2083 Vcombine_after_change_calls
= val
;
2086 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2087 Scombine_after_change_execute
, 0, 0, 0,
2088 doc
: /* This function is for use internally in the function `combine-after-change-calls'. */)
2091 ptrdiff_t count
= SPECPDL_INDEX ();
2092 ptrdiff_t beg
, end
, change
;
2093 ptrdiff_t begpos
, endpos
;
2096 if (NILP (combine_after_change_list
))
2099 /* It is rare for combine_after_change_buffer to be invalid, but
2100 possible. It can happen when combine-after-change-calls is
2101 non-nil, and insertion calls a file handler (e.g. through
2102 lock_file) which scribbles into a temp file -- cyd */
2103 if (!BUFFERP (combine_after_change_buffer
)
2104 || !BUFFER_LIVE_P (XBUFFER (combine_after_change_buffer
)))
2106 combine_after_change_list
= Qnil
;
2110 record_unwind_current_buffer ();
2112 Fset_buffer (combine_after_change_buffer
);
2114 /* # chars unchanged at beginning of buffer. */
2116 /* # chars unchanged at end of buffer. */
2118 /* Total amount of insertion (negative for deletion). */
2121 /* Scan the various individual changes,
2122 accumulating the range info in BEG, END and CHANGE. */
2123 for (tail
= combine_after_change_list
; CONSP (tail
);
2127 ptrdiff_t thisbeg
, thisend
, thischange
;
2129 /* Extract the info from the next element. */
2133 thisbeg
= XINT (XCAR (elt
));
2138 thisend
= XINT (XCAR (elt
));
2143 thischange
= XINT (XCAR (elt
));
2145 /* Merge this range into the accumulated range. */
2146 change
+= thischange
;
2153 /* Get the current start and end positions of the range
2154 that was changed. */
2158 /* We are about to handle these, so discard them. */
2159 combine_after_change_list
= Qnil
;
2161 /* Now run the after-change functions for real.
2162 Turn off the flag that defers them. */
2163 record_unwind_protect (Fcombine_after_change_execute_1
,
2164 Vcombine_after_change_calls
);
2165 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2166 update_compositions (begpos
, endpos
, CHECK_ALL
);
2168 return unbind_to (count
, Qnil
);
2172 syms_of_insdel (void)
2174 staticpro (&combine_after_change_list
);
2175 staticpro (&combine_after_change_buffer
);
2176 combine_after_change_list
= Qnil
;
2177 combine_after_change_buffer
= Qnil
;
2179 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls
,
2180 doc
: /* Used internally by the function `combine-after-change-calls' macro. */);
2181 Vcombine_after_change_calls
= Qnil
;
2183 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks
,
2184 doc
: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2185 This affects `before-change-functions' and `after-change-functions',
2186 as well as hooks attached to text properties and overlays. */);
2187 inhibit_modification_hooks
= 0;
2188 DEFSYM (Qinhibit_modification_hooks
, "inhibit-modification-hooks");
2190 DEFSYM (Qregion_extract_function
, "region-extract-function");
2192 defsubr (&Scombine_after_change_execute
);