1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985-1986, 1993-1995, 1997-2012
3 Free Software Foundation, Inc.
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/>. */
27 #include "intervals.h"
28 #include "character.h"
31 #include "blockinput.h"
32 #include "region-cache.h"
34 static void insert_from_string_1 (Lisp_Object string
,
35 ptrdiff_t pos
, ptrdiff_t pos_byte
,
36 ptrdiff_t nchars
, ptrdiff_t nbytes
,
37 int inherit
, int before_markers
);
38 static void insert_from_buffer_1 (struct buffer
*buf
,
39 ptrdiff_t from
, ptrdiff_t nchars
,
41 static void gap_left (ptrdiff_t charpos
, ptrdiff_t bytepos
, int newgap
);
42 static void gap_right (ptrdiff_t charpos
, ptrdiff_t bytepos
);
44 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
45 describing changes which happened while combine_after_change_calls
46 was nonzero. We use this to decide how to call them
47 once the deferral ends.
50 BEG-UNCHANGED is the number of chars before the changed range.
51 END-UNCHANGED is the number of chars after the changed range,
52 and CHANGE-AMOUNT is the number of characters inserted by the change
53 (negative for a deletion). */
54 static Lisp_Object combine_after_change_list
;
56 /* Buffer which combine_after_change_list is about. */
57 static Lisp_Object combine_after_change_buffer
;
59 Lisp_Object Qinhibit_modification_hooks
;
61 static void signal_before_change (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
63 #define CHECK_MARKERS() \
66 if (check_markers_debug_flag) \
74 register struct Lisp_Marker
*tail
;
75 int multibyte
= ! NILP (BVAR (current_buffer
, enable_multibyte_characters
));
77 for (tail
= BUF_MARKERS (current_buffer
); tail
; tail
= tail
->next
)
79 if (tail
->buffer
->text
!= current_buffer
->text
)
81 if (tail
->charpos
> Z
)
83 if (tail
->bytepos
> Z_BYTE
)
85 if (multibyte
&& ! CHAR_HEAD_P (FETCH_BYTE (tail
->bytepos
)))
90 /* Move gap to position CHARPOS.
91 Note that this can quit! */
94 move_gap (ptrdiff_t charpos
)
96 move_gap_both (charpos
, charpos_to_bytepos (charpos
));
99 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
100 Note that this can quit! */
103 move_gap_both (ptrdiff_t charpos
, ptrdiff_t bytepos
)
105 if (bytepos
< GPT_BYTE
)
106 gap_left (charpos
, bytepos
, 0);
107 else if (bytepos
> GPT_BYTE
)
108 gap_right (charpos
, bytepos
);
111 /* Move the gap to a position less than the current GPT.
112 BYTEPOS describes the new position as a byte position,
113 and CHARPOS is the corresponding char position.
114 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
117 gap_left (ptrdiff_t charpos
, ptrdiff_t bytepos
, int newgap
)
119 register unsigned char *to
, *from
;
120 register ptrdiff_t i
;
124 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
131 /* Now copy the characters. To move the gap down,
132 copy characters up. */
136 /* I gets number of characters left to copy. */
137 i
= new_s1
- bytepos
;
140 /* If a quit is requested, stop copying now.
141 Change BYTEPOS to be where we have actually moved the gap to. */
145 charpos
= BYTE_TO_CHAR (bytepos
);
148 /* Move at most 32000 chars before checking again for a quit. */
153 memmove (to
, from
, i
);
156 /* Adjust buffer data structure, to put the gap at BYTEPOS.
157 BYTEPOS is where the loop above stopped, which may be what
158 was specified or may be where a quit was detected. */
161 if (bytepos
< charpos
)
163 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
167 /* Move the gap to a position greater than the current GPT.
168 BYTEPOS describes the new position as a byte position,
169 and CHARPOS is the corresponding char position. */
172 gap_right (ptrdiff_t charpos
, ptrdiff_t bytepos
)
174 register unsigned char *to
, *from
;
175 register ptrdiff_t i
;
178 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
185 /* Now copy the characters. To move the gap up,
186 copy characters down. */
190 /* I gets number of characters left to copy. */
191 i
= bytepos
- new_s1
;
194 /* If a quit is requested, stop copying now.
195 Change BYTEPOS to be where we have actually moved the gap to. */
199 charpos
= BYTE_TO_CHAR (bytepos
);
202 /* Move at most 32000 chars before checking again for a quit. */
206 memmove (to
, from
, i
);
212 if (bytepos
< charpos
)
214 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
218 /* Adjust all markers for a deletion
219 whose range in bytes is FROM_BYTE to TO_BYTE.
220 The range in charpos is FROM to TO.
222 This function assumes that the gap is adjacent to
223 or inside of the range being deleted. */
226 adjust_markers_for_delete (ptrdiff_t from
, ptrdiff_t from_byte
,
227 ptrdiff_t to
, ptrdiff_t to_byte
)
230 register struct Lisp_Marker
*m
;
231 register ptrdiff_t charpos
;
233 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
235 charpos
= m
->charpos
;
240 /* If the marker is after the deletion,
241 relocate by number of chars / bytes deleted. */
244 m
->charpos
-= to
- from
;
245 m
->bytepos
-= to_byte
- from_byte
;
247 /* Here's the case where a marker is inside text being deleted. */
248 else if (charpos
> from
)
250 if (! m
->insertion_type
)
251 { /* Normal markers will end up at the beginning of the
252 re-inserted text after undoing a deletion, and must be
253 adjusted to move them to the correct place. */
254 XSETMISC (marker
, m
);
255 record_marker_adjustment (marker
, from
- charpos
);
257 else if (charpos
< to
)
258 { /* Before-insertion markers will automatically move forward
259 upon re-inserting the deleted text, so we have to arrange
260 for them to move backward to the correct position. */
261 XSETMISC (marker
, m
);
262 record_marker_adjustment (marker
, to
- charpos
);
265 m
->bytepos
= from_byte
;
267 /* Here's the case where a before-insertion marker is immediately
268 before the deleted region. */
269 else if (charpos
== from
&& m
->insertion_type
)
271 /* Undoing the change uses normal insertion, which will
272 incorrectly make MARKER move forward, so we arrange for it
273 to then move backward to the correct place at the beginning
274 of the deleted region. */
275 XSETMISC (marker
, m
);
276 record_marker_adjustment (marker
, to
- from
);
282 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
283 to TO / TO_BYTE. We have to relocate the charpos of every marker
284 that points after the insertion (but not their bytepos).
286 When a marker points at the insertion point,
287 we advance it if either its insertion-type is t
288 or BEFORE_MARKERS is true. */
291 adjust_markers_for_insert (ptrdiff_t from
, ptrdiff_t from_byte
,
292 ptrdiff_t to
, ptrdiff_t to_byte
, int before_markers
)
294 struct Lisp_Marker
*m
;
296 ptrdiff_t nchars
= to
- from
;
297 ptrdiff_t nbytes
= to_byte
- from_byte
;
299 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
301 eassert (m
->bytepos
>= m
->charpos
302 && m
->bytepos
- m
->charpos
<= Z_BYTE
- Z
);
304 if (m
->bytepos
== from_byte
)
306 if (m
->insertion_type
|| before_markers
)
308 m
->bytepos
= to_byte
;
310 if (m
->insertion_type
)
314 else if (m
->bytepos
> from_byte
)
316 m
->bytepos
+= nbytes
;
317 m
->charpos
+= nchars
;
321 /* Adjusting only markers whose insertion-type is t may result in
322 - disordered start and end in overlays, and
323 - disordered overlays in the slot `overlays_before' of current_buffer. */
326 fix_start_end_in_overlays (from
, to
);
327 fix_overlays_before (current_buffer
, from
, to
);
331 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
333 This is used only when the value of point changes due to an insert
334 or delete; it does not represent a conceptual change in point as a
335 marker. In particular, point is not crossing any interval
336 boundaries, so there's no need to use the usual SET_PT macro. In
337 fact it would be incorrect to do so, because either the old or the
338 new value of point is out of sync with the current set of
342 adjust_point (ptrdiff_t nchars
, ptrdiff_t nbytes
)
344 SET_BUF_PT_BOTH (current_buffer
, PT
+ nchars
, PT_BYTE
+ nbytes
);
345 /* In a single-byte buffer, the two positions must be equal. */
346 eassert (PT_BYTE
>= PT
&& PT_BYTE
- PT
<= ZV_BYTE
- ZV
);
349 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
350 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
351 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
355 adjust_markers_for_replace (ptrdiff_t from
, ptrdiff_t from_byte
,
356 ptrdiff_t old_chars
, ptrdiff_t old_bytes
,
357 ptrdiff_t new_chars
, ptrdiff_t new_bytes
)
359 register struct Lisp_Marker
*m
;
360 ptrdiff_t prev_to_byte
= from_byte
+ old_bytes
;
361 ptrdiff_t diff_chars
= new_chars
- old_chars
;
362 ptrdiff_t diff_bytes
= new_bytes
- old_bytes
;
364 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
366 if (m
->bytepos
>= prev_to_byte
)
368 m
->charpos
+= diff_chars
;
369 m
->bytepos
+= diff_bytes
;
371 else if (m
->bytepos
> from_byte
)
374 m
->bytepos
= from_byte
;
383 buffer_overflow (void)
385 error ("Maximum buffer size exceeded");
388 /* Make the gap NBYTES_ADDED bytes longer. */
391 make_gap_larger (ptrdiff_t nbytes_added
)
394 ptrdiff_t real_gap_loc
;
395 ptrdiff_t real_gap_loc_byte
;
396 ptrdiff_t old_gap_size
;
397 ptrdiff_t current_size
= Z_BYTE
- BEG_BYTE
+ GAP_SIZE
;
398 enum { enough_for_a_while
= 2000 };
400 if (BUF_BYTES_MAX
- current_size
< nbytes_added
)
403 /* If we have to get more space, get enough to last a while;
404 but do not exceed the maximum buffer size. */
405 nbytes_added
= min (nbytes_added
+ enough_for_a_while
,
406 BUF_BYTES_MAX
- current_size
);
408 enlarge_buffer_text (current_buffer
, nbytes_added
);
410 /* Prevent quitting in move_gap. */
415 real_gap_loc_byte
= GPT_BYTE
;
416 old_gap_size
= GAP_SIZE
;
418 /* Call the newly allocated space a gap at the end of the whole space. */
420 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
421 GAP_SIZE
= nbytes_added
;
423 /* Move the new gap down to be consecutive with the end of the old one.
424 This adjusts the markers properly too. */
425 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
427 /* Now combine the two into one large gap. */
428 GAP_SIZE
+= old_gap_size
;
430 GPT_BYTE
= real_gap_loc_byte
;
438 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
440 /* Make the gap NBYTES_REMOVED bytes shorter. */
443 make_gap_smaller (ptrdiff_t nbytes_removed
)
446 ptrdiff_t real_gap_loc
;
447 ptrdiff_t real_gap_loc_byte
;
449 ptrdiff_t real_Z_byte
;
450 ptrdiff_t real_beg_unchanged
;
451 ptrdiff_t new_gap_size
;
453 /* Make sure the gap is at least 20 bytes. */
454 if (GAP_SIZE
- nbytes_removed
< 20)
455 nbytes_removed
= GAP_SIZE
- 20;
457 /* Prevent quitting in move_gap. */
462 real_gap_loc_byte
= GPT_BYTE
;
463 new_gap_size
= GAP_SIZE
- nbytes_removed
;
465 real_Z_byte
= Z_BYTE
;
466 real_beg_unchanged
= BEG_UNCHANGED
;
468 /* Pretend that the last unwanted part of the gap is the entire gap,
469 and that the first desired part of the gap is part of the buffer
471 memset (GPT_ADDR
, 0, new_gap_size
);
473 GPT_BYTE
+= new_gap_size
;
475 Z_BYTE
+= new_gap_size
;
476 GAP_SIZE
= nbytes_removed
;
478 /* Move the unwanted pretend gap to the end of the buffer. This
479 adjusts the markers properly too. */
480 gap_right (Z
, Z_BYTE
);
482 enlarge_buffer_text (current_buffer
, -nbytes_removed
);
484 /* Now restore the desired gap. */
485 GAP_SIZE
= new_gap_size
;
487 GPT_BYTE
= real_gap_loc_byte
;
489 Z_BYTE
= real_Z_byte
;
490 BEG_UNCHANGED
= real_beg_unchanged
;
498 #endif /* USE_MMAP_FOR_BUFFERS || REL_ALLOC || DOUG_LEA_MALLOC */
501 make_gap (ptrdiff_t nbytes_added
)
503 if (nbytes_added
>= 0)
504 make_gap_larger (nbytes_added
);
505 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
507 make_gap_smaller (-nbytes_added
);
511 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
512 FROM_MULTIBYTE says whether the incoming text is multibyte.
513 TO_MULTIBYTE says whether to store the text as multibyte.
514 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
516 Return the number of bytes stored at TO_ADDR. */
519 copy_text (const unsigned char *from_addr
, unsigned char *to_addr
,
520 ptrdiff_t nbytes
, int from_multibyte
, int to_multibyte
)
522 if (from_multibyte
== to_multibyte
)
524 memcpy (to_addr
, from_addr
, nbytes
);
527 else if (from_multibyte
)
529 ptrdiff_t nchars
= 0;
530 ptrdiff_t bytes_left
= nbytes
;
532 while (bytes_left
> 0)
535 c
= STRING_CHAR_AND_LENGTH (from_addr
, thislen
);
536 if (! ASCII_CHAR_P (c
))
539 from_addr
+= thislen
;
540 bytes_left
-= thislen
;
547 unsigned char *initial_to_addr
= to_addr
;
549 /* Convert single-byte to multibyte. */
552 int c
= *from_addr
++;
554 if (!ASCII_CHAR_P (c
))
556 c
= BYTE8_TO_CHAR (c
);
557 to_addr
+= CHAR_STRING (c
, to_addr
);
561 /* Special case for speed. */
562 *to_addr
++ = c
, nbytes
--;
564 return to_addr
- initial_to_addr
;
568 /* Insert a string of specified length before point.
569 This function judges multibyteness based on
570 enable_multibyte_characters in the current buffer;
571 it never converts between single-byte and multibyte.
573 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
574 prepare_to_modify_buffer could relocate the text. */
577 insert (const char *string
, ptrdiff_t nbytes
)
581 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
582 insert_1_both (string
, len
, nbytes
, 0, 1, 0);
584 signal_after_change (opoint
, 0, len
);
585 update_compositions (opoint
, PT
, CHECK_BORDER
);
589 /* Likewise, but inherit text properties from neighboring characters. */
592 insert_and_inherit (const char *string
, ptrdiff_t nbytes
)
596 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
597 insert_1_both (string
, len
, nbytes
, 1, 1, 0);
599 signal_after_change (opoint
, 0, len
);
600 update_compositions (opoint
, PT
, CHECK_BORDER
);
604 /* Insert the character C before point. Do not inherit text properties. */
609 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
612 if (! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
613 len
= CHAR_STRING (c
, str
);
620 insert ((char *) str
, len
);
623 /* Insert the null-terminated string S before point. */
626 insert_string (const char *s
)
628 insert (s
, strlen (s
));
631 /* Like `insert' except that all markers pointing at the place where
632 the insertion happens are adjusted to point after it.
633 Don't use this function to insert part of a Lisp string,
634 since gc could happen and relocate it. */
637 insert_before_markers (const char *string
, ptrdiff_t nbytes
)
641 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
642 insert_1_both (string
, len
, nbytes
, 0, 1, 1);
644 signal_after_change (opoint
, 0, len
);
645 update_compositions (opoint
, PT
, CHECK_BORDER
);
649 /* Likewise, but inherit text properties from neighboring characters. */
652 insert_before_markers_and_inherit (const char *string
,
657 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
658 insert_1_both (string
, len
, nbytes
, 1, 1, 1);
660 signal_after_change (opoint
, 0, len
);
661 update_compositions (opoint
, PT
, CHECK_BORDER
);
665 /* Subroutine used by the insert functions above. */
668 insert_1 (const char *string
, ptrdiff_t nbytes
,
669 int inherit
, int prepare
, int before_markers
)
671 insert_1_both (string
, chars_in_text ((unsigned char *) string
, nbytes
),
672 nbytes
, inherit
, prepare
, before_markers
);
676 #ifdef BYTE_COMBINING_DEBUG
678 /* See if the bytes before POS/POS_BYTE combine with bytes
679 at the start of STRING to form a single character.
680 If so, return the number of bytes at the start of STRING
681 which combine in this way. Otherwise, return 0. */
684 count_combining_before (const unsigned char *string
, ptrdiff_t length
,
685 ptrdiff_t pos
, ptrdiff_t pos_byte
)
687 int len
, combining_bytes
;
688 const unsigned char *p
;
690 if (NILP (current_buffer
->enable_multibyte_characters
))
693 /* At first, we can exclude the following cases:
694 (1) STRING[0] can't be a following byte of multibyte sequence.
695 (2) POS is the start of the current buffer.
696 (3) A character before POS is not a multibyte character. */
697 if (length
== 0 || CHAR_HEAD_P (*string
)) /* case (1) */
699 if (pos_byte
== BEG_BYTE
) /* case (2) */
702 p
= BYTE_POS_ADDR (pos_byte
- 1);
703 while (! CHAR_HEAD_P (*p
)) p
--, len
++;
704 if (! LEADING_CODE_P (*p
)) /* case (3) */
707 combining_bytes
= BYTES_BY_CHAR_HEAD (*p
) - len
;
708 if (combining_bytes
<= 0)
709 /* The character preceding POS is, complete and no room for
710 combining bytes (combining_bytes == 0), or an independent 8-bit
711 character (combining_bytes < 0). */
714 /* We have a combination situation. Count the bytes at STRING that
717 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
720 return (combining_bytes
< p
- string
? combining_bytes
: p
- string
);
723 /* See if the bytes after POS/POS_BYTE combine with bytes
724 at the end of STRING to form a single character.
725 If so, return the number of bytes after POS/POS_BYTE
726 which combine in this way. Otherwise, return 0. */
729 count_combining_after (const unsigned char *string
,
730 ptrdiff_t length
, ptrdiff_t pos
, ptrdiff_t pos_byte
)
732 ptrdiff_t opos_byte
= pos_byte
;
737 if (NILP (current_buffer
->enable_multibyte_characters
))
740 /* At first, we can exclude the following cases:
741 (1) The last byte of STRING is an ASCII.
742 (2) POS is the last of the current buffer.
743 (3) A character at POS can't be a following byte of multibyte
745 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1])) /* case (1) */
747 if (pos_byte
== Z_BYTE
) /* case (2) */
749 bufp
= BYTE_POS_ADDR (pos_byte
);
750 if (CHAR_HEAD_P (*bufp
)) /* case (3) */
754 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
760 /* All characters in STRING are not character head. We must
761 check also preceding bytes at POS. We are sure that the gap
763 unsigned char *p
= BEG_ADDR
;
765 while (i
>= 0 && ! CHAR_HEAD_P (p
[i
]))
767 if (i
< 0 || !LEADING_CODE_P (p
[i
]))
770 bytes
= BYTES_BY_CHAR_HEAD (p
[i
]);
771 return (bytes
<= pos_byte
- 1 - i
+ length
773 : bytes
- (pos_byte
- 1 - i
+ length
));
775 if (!LEADING_CODE_P (string
[i
]))
778 bytes
= BYTES_BY_CHAR_HEAD (string
[i
]) - (length
- i
);
780 while (!CHAR_HEAD_P (*bufp
)) bufp
++, pos_byte
++;
782 return (bytes
<= pos_byte
- opos_byte
? bytes
: pos_byte
- opos_byte
);
788 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
789 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
790 are the same as in insert_1. */
793 insert_1_both (const char *string
,
794 ptrdiff_t nchars
, ptrdiff_t nbytes
,
795 int inherit
, int prepare
, int before_markers
)
800 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
804 /* Do this before moving and increasing the gap,
805 because the before-change hooks might move the gap
806 or make it smaller. */
807 prepare_to_modify_buffer (PT
, PT
, NULL
);
810 move_gap_both (PT
, PT_BYTE
);
811 if (GAP_SIZE
< nbytes
)
812 make_gap (nbytes
- GAP_SIZE
);
814 #ifdef BYTE_COMBINING_DEBUG
815 if (count_combining_before (string
, nbytes
, PT
, PT_BYTE
)
816 || count_combining_after (string
, nbytes
, PT
, PT_BYTE
))
820 /* Record deletion of the surrounding text that combines with
821 the insertion. This, together with recording the insertion,
822 will add up to the right stuff in the undo list. */
823 record_insert (PT
, nchars
);
825 CHARS_MODIFF
= MODIFF
;
827 memcpy (GPT_ADDR
, string
, nbytes
);
836 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
841 /* The insert may have been in the unchanged region, so check again. */
842 if (Z
- GPT
< END_UNCHANGED
)
843 END_UNCHANGED
= Z
- GPT
;
845 adjust_overlays_for_insert (PT
, nchars
);
846 adjust_markers_for_insert (PT
, PT_BYTE
,
847 PT
+ nchars
, PT_BYTE
+ nbytes
,
850 if (BUF_INTERVALS (current_buffer
) != 0)
851 offset_intervals (current_buffer
, PT
, nchars
);
853 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
854 set_text_properties (make_number (PT
), make_number (PT
+ nchars
),
857 adjust_point (nchars
, nbytes
);
862 /* Insert the part of the text of STRING, a Lisp object assumed to be
863 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
864 starting at position POS / POS_BYTE. If the text of STRING has properties,
865 copy them into the buffer.
867 It does not work to use `insert' for this, because a GC could happen
868 before we copy the stuff into the buffer, and relocate the string
869 without insert noticing. */
872 insert_from_string (Lisp_Object string
, ptrdiff_t pos
, ptrdiff_t pos_byte
,
873 ptrdiff_t length
, ptrdiff_t length_byte
, int inherit
)
875 ptrdiff_t opoint
= PT
;
877 if (SCHARS (string
) == 0)
880 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
882 signal_after_change (opoint
, 0, PT
- opoint
);
883 update_compositions (opoint
, PT
, CHECK_BORDER
);
886 /* Like `insert_from_string' except that all markers pointing
887 at the place where the insertion happens are adjusted to point after it. */
890 insert_from_string_before_markers (Lisp_Object string
,
891 ptrdiff_t pos
, ptrdiff_t pos_byte
,
892 ptrdiff_t length
, ptrdiff_t length_byte
,
895 ptrdiff_t opoint
= PT
;
897 if (SCHARS (string
) == 0)
900 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
902 signal_after_change (opoint
, 0, PT
- opoint
);
903 update_compositions (opoint
, PT
, CHECK_BORDER
);
906 /* Subroutine of the insertion functions above. */
909 insert_from_string_1 (Lisp_Object string
, ptrdiff_t pos
, ptrdiff_t pos_byte
,
910 ptrdiff_t nchars
, ptrdiff_t nbytes
,
911 int inherit
, int before_markers
)
914 ptrdiff_t outgoing_nbytes
= nbytes
;
917 /* Make OUTGOING_NBYTES describe the text
918 as it will be inserted in this buffer. */
920 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
921 outgoing_nbytes
= nchars
;
922 else if (! STRING_MULTIBYTE (string
))
924 = count_size_as_multibyte (SDATA (string
) + pos_byte
,
928 /* Do this before moving and increasing the gap,
929 because the before-change hooks might move the gap
930 or make it smaller. */
931 prepare_to_modify_buffer (PT
, PT
, NULL
);
934 move_gap_both (PT
, PT_BYTE
);
935 if (GAP_SIZE
< outgoing_nbytes
)
936 make_gap (outgoing_nbytes
- GAP_SIZE
);
939 /* Copy the string text into the buffer, perhaps converting
940 between single-byte and multibyte. */
941 copy_text (SDATA (string
) + pos_byte
, GPT_ADDR
, nbytes
,
942 STRING_MULTIBYTE (string
),
943 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
945 #ifdef BYTE_COMBINING_DEBUG
946 /* We have copied text into the gap, but we have not altered
947 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
948 to these functions and get the same results as we would
949 have got earlier on. Meanwhile, PT_ADDR does point to
950 the text that has been stored by copy_text. */
951 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
952 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
956 record_insert (PT
, nchars
);
958 CHARS_MODIFF
= MODIFF
;
960 GAP_SIZE
-= outgoing_nbytes
;
964 GPT_BYTE
+= outgoing_nbytes
;
965 ZV_BYTE
+= outgoing_nbytes
;
966 Z_BYTE
+= outgoing_nbytes
;
967 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
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. */
1021 adjust_overlays_for_insert (GPT
- nchars
, nchars
);
1022 adjust_markers_for_insert (GPT
- nchars
, GPT_BYTE
- nbytes
,
1025 if (BUF_INTERVALS (current_buffer
) != 0)
1027 offset_intervals (current_buffer
, GPT
- nchars
, nchars
);
1028 graft_intervals_into_buffer (NULL_INTERVAL
, GPT
- nchars
, nchars
,
1032 if (GPT
- nchars
< PT
)
1033 adjust_point (nchars
, nbytes
);
1038 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1039 current buffer. If the text in BUF has properties, they are absorbed
1040 into the current buffer.
1042 It does not work to use `insert' for this, because a malloc could happen
1043 and relocate BUF's text before the copy happens. */
1046 insert_from_buffer (struct buffer
*buf
,
1047 ptrdiff_t charpos
, ptrdiff_t nchars
, int inherit
)
1049 ptrdiff_t opoint
= PT
;
1051 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1052 signal_after_change (opoint
, 0, PT
- opoint
);
1053 update_compositions (opoint
, PT
, CHECK_BORDER
);
1057 insert_from_buffer_1 (struct buffer
*buf
,
1058 ptrdiff_t from
, ptrdiff_t nchars
, int inherit
)
1060 ptrdiff_t chunk
, chunk_expanded
;
1061 ptrdiff_t from_byte
= buf_charpos_to_bytepos (buf
, from
);
1062 ptrdiff_t to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1063 ptrdiff_t incoming_nbytes
= to_byte
- from_byte
;
1064 ptrdiff_t outgoing_nbytes
= incoming_nbytes
;
1067 /* Make OUTGOING_NBYTES describe the text
1068 as it will be inserted in this buffer. */
1070 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1071 outgoing_nbytes
= nchars
;
1072 else if (NILP (BVAR (buf
, enable_multibyte_characters
)))
1074 ptrdiff_t outgoing_before_gap
= 0;
1075 ptrdiff_t outgoing_after_gap
= 0;
1077 if (from
< BUF_GPT (buf
))
1079 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1080 if (chunk
> incoming_nbytes
)
1081 chunk
= incoming_nbytes
;
1083 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1089 if (chunk
< incoming_nbytes
)
1091 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
,
1093 incoming_nbytes
- chunk
);
1095 outgoing_nbytes
= outgoing_before_gap
+ outgoing_after_gap
;
1098 /* Do this before moving and increasing the gap,
1099 because the before-change hooks might move the gap
1100 or make it smaller. */
1101 prepare_to_modify_buffer (PT
, PT
, NULL
);
1104 move_gap_both (PT
, PT_BYTE
);
1105 if (GAP_SIZE
< outgoing_nbytes
)
1106 make_gap (outgoing_nbytes
- GAP_SIZE
);
1108 if (from
< BUF_GPT (buf
))
1110 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1111 if (chunk
> incoming_nbytes
)
1112 chunk
= incoming_nbytes
;
1113 /* Record number of output bytes, so we know where
1114 to put the output from the second copy_text. */
1116 = copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1118 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1119 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1122 chunk_expanded
= chunk
= 0;
1124 if (chunk
< incoming_nbytes
)
1125 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1126 GPT_ADDR
+ chunk_expanded
, incoming_nbytes
- chunk
,
1127 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1128 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1130 #ifdef BYTE_COMBINING_DEBUG
1131 /* We have copied text into the gap, but we have not altered
1132 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1133 to these functions and get the same results as we would
1134 have got earlier on. Meanwhile, GPT_ADDR does point to
1135 the text that has been stored by copy_text. */
1136 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1137 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1141 record_insert (PT
, nchars
);
1143 CHARS_MODIFF
= MODIFF
;
1145 GAP_SIZE
-= outgoing_nbytes
;
1149 GPT_BYTE
+= outgoing_nbytes
;
1150 ZV_BYTE
+= outgoing_nbytes
;
1151 Z_BYTE
+= outgoing_nbytes
;
1152 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1157 /* The insert may have been in the unchanged region, so check again. */
1158 if (Z
- GPT
< END_UNCHANGED
)
1159 END_UNCHANGED
= Z
- GPT
;
1161 adjust_overlays_for_insert (PT
, nchars
);
1162 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1163 PT_BYTE
+ outgoing_nbytes
,
1166 if (BUF_INTERVALS (current_buffer
) != 0)
1167 offset_intervals (current_buffer
, PT
, nchars
);
1169 /* Get the intervals for the part of the string we are inserting. */
1170 intervals
= BUF_INTERVALS (buf
);
1171 if (nchars
< BUF_Z (buf
) - BUF_BEG (buf
))
1173 if (buf
== current_buffer
&& PT
<= from
)
1175 intervals
= copy_intervals (intervals
, from
, nchars
);
1178 /* Insert those intervals. */
1179 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1181 adjust_point (nchars
, outgoing_nbytes
);
1184 /* Record undo information and adjust markers and position keepers for
1185 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1186 chars (LEN_BYTE bytes) which resides in the gap just after
1189 PREV_TEXT nil means the new text was just inserted. */
1192 adjust_after_replace (ptrdiff_t from
, ptrdiff_t from_byte
,
1193 Lisp_Object prev_text
, ptrdiff_t len
, ptrdiff_t len_byte
)
1195 ptrdiff_t nchars_del
= 0, nbytes_del
= 0;
1197 #ifdef BYTE_COMBINING_DEBUG
1198 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1199 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1203 if (STRINGP (prev_text
))
1205 nchars_del
= SCHARS (prev_text
);
1206 nbytes_del
= SBYTES (prev_text
);
1209 /* Update various buffer positions for the new text. */
1210 GAP_SIZE
-= len_byte
;
1212 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1213 GPT
+= len
; GPT_BYTE
+= len_byte
;
1214 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1217 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1220 adjust_markers_for_insert (from
, from_byte
,
1221 from
+ len
, from_byte
+ len_byte
, 0);
1223 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1226 record_delete (from
, prev_text
);
1227 record_insert (from
, len
);
1230 if (len
> nchars_del
)
1231 adjust_overlays_for_insert (from
, len
- nchars_del
);
1232 else if (len
< nchars_del
)
1233 adjust_overlays_for_delete (from
, nchars_del
- len
);
1234 if (BUF_INTERVALS (current_buffer
) != 0)
1236 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1240 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1242 /* As byte combining will decrease Z, we must check this again. */
1243 if (Z
- GPT
< END_UNCHANGED
)
1244 END_UNCHANGED
= Z
- GPT
;
1249 evaporate_overlays (from
);
1251 CHARS_MODIFF
= MODIFF
;
1254 /* Record undo information, adjust markers and position keepers for an
1255 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1256 text already exists in the current buffer but character length (TO
1257 - FROM) may be incorrect, the correct length is NEWLEN. */
1260 adjust_after_insert (ptrdiff_t from
, ptrdiff_t from_byte
,
1261 ptrdiff_t to
, ptrdiff_t to_byte
, ptrdiff_t newlen
)
1263 ptrdiff_t len
= to
- from
, len_byte
= to_byte
- from_byte
;
1266 move_gap_both (to
, to_byte
);
1267 GAP_SIZE
+= len_byte
;
1268 GPT
-= len
; GPT_BYTE
-= len_byte
;
1269 ZV
-= len
; ZV_BYTE
-= len_byte
;
1270 Z
-= len
; Z_BYTE
-= len_byte
;
1271 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1274 /* Replace the text from character positions FROM to TO with NEW,
1275 If PREPARE is nonzero, call prepare_to_modify_buffer.
1276 If INHERIT, the newly inserted text should inherit text properties
1277 from the surrounding non-deleted text. */
1279 /* Note that this does not yet handle markers quite right.
1280 Also it needs to record a single undo-entry that does a replacement
1281 rather than a separate delete and insert.
1282 That way, undo will also handle markers properly.
1284 But if MARKERS is 0, don't relocate markers. */
1287 replace_range (ptrdiff_t from
, ptrdiff_t to
, Lisp_Object
new,
1288 int prepare
, int inherit
, int markers
)
1290 ptrdiff_t inschars
= SCHARS (new);
1291 ptrdiff_t insbytes
= SBYTES (new);
1292 ptrdiff_t from_byte
, to_byte
;
1293 ptrdiff_t nbytes_del
, nchars_del
;
1294 struct gcpro gcpro1
;
1296 ptrdiff_t outgoing_insbytes
= insbytes
;
1297 Lisp_Object deletion
;
1306 ptrdiff_t range_length
= to
- from
;
1307 prepare_to_modify_buffer (from
, to
, &from
);
1308 to
= from
+ range_length
;
1313 /* Make args be valid. */
1319 from_byte
= CHAR_TO_BYTE (from
);
1320 to_byte
= CHAR_TO_BYTE (to
);
1322 nchars_del
= to
- from
;
1323 nbytes_del
= to_byte
- from_byte
;
1325 if (nbytes_del
<= 0 && insbytes
== 0)
1328 /* Make OUTGOING_INSBYTES describe the text
1329 as it will be inserted in this buffer. */
1331 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1332 outgoing_insbytes
= inschars
;
1333 else if (! STRING_MULTIBYTE (new))
1335 = count_size_as_multibyte (SDATA (new), insbytes
);
1339 /* Make sure the gap is somewhere in or next to what we are deleting. */
1341 gap_right (from
, from_byte
);
1343 gap_left (to
, to_byte
, 0);
1345 /* Even if we don't record for undo, we must keep the original text
1346 because we may have to recover it because of inappropriate byte
1348 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1349 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1351 GAP_SIZE
+= nbytes_del
;
1354 ZV_BYTE
-= nbytes_del
;
1355 Z_BYTE
-= nbytes_del
;
1357 GPT_BYTE
= from_byte
;
1358 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1363 if (GPT
- BEG
< BEG_UNCHANGED
)
1364 BEG_UNCHANGED
= GPT
- BEG
;
1365 if (Z
- GPT
< END_UNCHANGED
)
1366 END_UNCHANGED
= Z
- GPT
;
1368 if (GAP_SIZE
< outgoing_insbytes
)
1369 make_gap (outgoing_insbytes
- GAP_SIZE
);
1371 /* Copy the string text into the buffer, perhaps converting
1372 between single-byte and multibyte. */
1373 copy_text (SDATA (new), GPT_ADDR
, insbytes
,
1374 STRING_MULTIBYTE (new),
1375 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1377 #ifdef BYTE_COMBINING_DEBUG
1378 /* We have copied text into the gap, but we have not marked
1379 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1380 here, for both the previous text and the following text.
1381 Meanwhile, GPT_ADDR does point to
1382 the text that has been stored by copy_text. */
1383 if (count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
)
1384 || count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
))
1388 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1390 /* Record the insertion first, so that when we undo,
1391 the deletion will be undone first. Thus, undo
1392 will insert before deleting, and thus will keep
1393 the markers before and after this text separate. */
1394 record_insert (from
+ SCHARS (deletion
), inschars
);
1395 record_delete (from
, deletion
);
1398 GAP_SIZE
-= outgoing_insbytes
;
1402 GPT_BYTE
+= outgoing_insbytes
;
1403 ZV_BYTE
+= outgoing_insbytes
;
1404 Z_BYTE
+= outgoing_insbytes
;
1405 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1410 /* Adjust the overlay center as needed. This must be done after
1411 adjusting the markers that bound the overlays. */
1412 adjust_overlays_for_delete (from
, nchars_del
);
1413 adjust_overlays_for_insert (from
, inschars
);
1415 /* Adjust markers for the deletion and the insertion. */
1417 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1418 inschars
, outgoing_insbytes
);
1420 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1422 /* Get the intervals for the part of the string we are inserting--
1423 not including the combined-before bytes. */
1424 intervals
= STRING_INTERVALS (new);
1425 /* Insert those intervals. */
1426 graft_intervals_into_buffer (intervals
, from
, inschars
,
1427 current_buffer
, inherit
);
1429 /* Relocate point as if it were a marker. */
1431 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1432 (from_byte
+ outgoing_insbytes
1433 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1435 if (outgoing_insbytes
== 0)
1436 evaporate_overlays (from
);
1441 CHARS_MODIFF
= MODIFF
;
1444 signal_after_change (from
, nchars_del
, GPT
- from
);
1445 update_compositions (from
, GPT
, CHECK_BORDER
);
1448 /* Replace the text from character positions FROM to TO with
1449 the text in INS of length INSCHARS.
1450 Keep the text properties that applied to the old characters
1451 (extending them to all the new chars if there are more new chars).
1453 Note that this does not yet handle markers quite right.
1455 If MARKERS is nonzero, relocate markers.
1457 Unlike most functions at this level, never call
1458 prepare_to_modify_buffer and never call signal_after_change. */
1461 replace_range_2 (ptrdiff_t from
, ptrdiff_t from_byte
,
1462 ptrdiff_t to
, ptrdiff_t to_byte
,
1463 const char *ins
, ptrdiff_t inschars
, ptrdiff_t insbytes
,
1466 ptrdiff_t nbytes_del
, nchars_del
;
1470 nchars_del
= to
- from
;
1471 nbytes_del
= to_byte
- from_byte
;
1473 if (nbytes_del
<= 0 && insbytes
== 0)
1476 /* Make sure the gap is somewhere in or next to what we are deleting. */
1478 gap_right (from
, from_byte
);
1480 gap_left (to
, to_byte
, 0);
1482 GAP_SIZE
+= nbytes_del
;
1485 ZV_BYTE
-= nbytes_del
;
1486 Z_BYTE
-= nbytes_del
;
1488 GPT_BYTE
= from_byte
;
1489 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1494 if (GPT
- BEG
< BEG_UNCHANGED
)
1495 BEG_UNCHANGED
= GPT
- BEG
;
1496 if (Z
- GPT
< END_UNCHANGED
)
1497 END_UNCHANGED
= Z
- GPT
;
1499 if (GAP_SIZE
< insbytes
)
1500 make_gap (insbytes
- GAP_SIZE
);
1502 /* Copy the replacement text into the buffer. */
1503 memcpy (GPT_ADDR
, ins
, insbytes
);
1505 #ifdef BYTE_COMBINING_DEBUG
1506 /* We have copied text into the gap, but we have not marked
1507 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1508 here, for both the previous text and the following text.
1509 Meanwhile, GPT_ADDR does point to
1510 the text that has been stored by copy_text. */
1511 if (count_combining_before (GPT_ADDR
, insbytes
, from
, from_byte
)
1512 || count_combining_after (GPT_ADDR
, insbytes
, from
, from_byte
))
1516 GAP_SIZE
-= insbytes
;
1520 GPT_BYTE
+= insbytes
;
1521 ZV_BYTE
+= insbytes
;
1523 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1528 /* Adjust the overlay center as needed. This must be done after
1529 adjusting the markers that bound the overlays. */
1530 if (nchars_del
!= inschars
)
1532 adjust_overlays_for_insert (from
, inschars
);
1533 adjust_overlays_for_delete (from
+ inschars
, nchars_del
);
1536 /* Adjust markers for the deletion and the insertion. */
1538 && ! (nchars_del
== 1 && inschars
== 1 && nbytes_del
== insbytes
))
1539 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1540 inschars
, insbytes
);
1542 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1544 /* Relocate point as if it were a marker. */
1545 if (from
< PT
&& (nchars_del
!= inschars
|| nbytes_del
!= insbytes
))
1548 /* PT was within the deleted text. Move it to FROM. */
1549 adjust_point (from
- PT
, from_byte
- PT_BYTE
);
1551 adjust_point (inschars
- nchars_del
, insbytes
- nbytes_del
);
1555 evaporate_overlays (from
);
1560 CHARS_MODIFF
= MODIFF
;
1563 /* Delete characters in current buffer
1564 from FROM up to (but not including) TO.
1565 If TO comes before FROM, we delete nothing. */
1568 del_range (ptrdiff_t from
, ptrdiff_t to
)
1570 del_range_1 (from
, to
, 1, 0);
1573 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1574 RET_STRING says to return the deleted text. */
1577 del_range_1 (ptrdiff_t from
, ptrdiff_t to
, int prepare
, int ret_string
)
1579 ptrdiff_t from_byte
, to_byte
;
1580 Lisp_Object deletion
;
1581 struct gcpro gcpro1
;
1583 /* Make args be valid */
1594 ptrdiff_t range_length
= to
- from
;
1595 prepare_to_modify_buffer (from
, to
, &from
);
1596 to
= min (ZV
, from
+ range_length
);
1599 from_byte
= CHAR_TO_BYTE (from
);
1600 to_byte
= CHAR_TO_BYTE (to
);
1602 deletion
= del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
);
1604 signal_after_change (from
, to
- from
, 0);
1605 update_compositions (from
, from
, CHECK_HEAD
);
1610 /* Like del_range_1 but args are byte positions, not char positions. */
1613 del_range_byte (ptrdiff_t from_byte
, ptrdiff_t to_byte
, int prepare
)
1617 /* Make args be valid */
1618 if (from_byte
< BEGV_BYTE
)
1619 from_byte
= BEGV_BYTE
;
1620 if (to_byte
> ZV_BYTE
)
1623 if (to_byte
<= from_byte
)
1626 from
= BYTE_TO_CHAR (from_byte
);
1627 to
= BYTE_TO_CHAR (to_byte
);
1631 ptrdiff_t old_from
= from
, old_to
= Z
- to
;
1632 ptrdiff_t range_length
= to
- from
;
1633 prepare_to_modify_buffer (from
, to
, &from
);
1634 to
= from
+ range_length
;
1636 if (old_from
!= from
)
1637 from_byte
= CHAR_TO_BYTE (from
);
1643 else if (old_to
== Z
- to
)
1644 to_byte
= CHAR_TO_BYTE (to
);
1647 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1648 signal_after_change (from
, to
- from
, 0);
1649 update_compositions (from
, from
, CHECK_HEAD
);
1652 /* Like del_range_1, but positions are specified both as charpos
1656 del_range_both (ptrdiff_t from
, ptrdiff_t from_byte
,
1657 ptrdiff_t to
, ptrdiff_t to_byte
, int prepare
)
1659 /* Make args be valid */
1660 if (from_byte
< BEGV_BYTE
)
1661 from_byte
= BEGV_BYTE
;
1662 if (to_byte
> ZV_BYTE
)
1665 if (to_byte
<= from_byte
)
1675 ptrdiff_t old_from
= from
, old_to
= Z
- to
;
1676 ptrdiff_t range_length
= to
- from
;
1677 prepare_to_modify_buffer (from
, to
, &from
);
1678 to
= from
+ range_length
;
1680 if (old_from
!= from
)
1681 from_byte
= CHAR_TO_BYTE (from
);
1687 else if (old_to
== Z
- to
)
1688 to_byte
= CHAR_TO_BYTE (to
);
1691 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1692 signal_after_change (from
, to
- from
, 0);
1693 update_compositions (from
, from
, CHECK_HEAD
);
1696 /* Delete a range of text, specified both as character positions
1697 and byte positions. FROM and TO are character positions,
1698 while FROM_BYTE and TO_BYTE are byte positions.
1699 If RET_STRING is true, the deleted area is returned as a string. */
1702 del_range_2 (ptrdiff_t from
, ptrdiff_t from_byte
,
1703 ptrdiff_t to
, ptrdiff_t to_byte
, int ret_string
)
1705 register ptrdiff_t nbytes_del
, nchars_del
;
1706 Lisp_Object deletion
;
1710 nchars_del
= to
- from
;
1711 nbytes_del
= to_byte
- from_byte
;
1713 /* Make sure the gap is somewhere in or next to what we are deleting. */
1715 gap_right (from
, from_byte
);
1717 gap_left (to
, to_byte
, 0);
1719 #ifdef BYTE_COMBINING_DEBUG
1720 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
1721 Z_BYTE
- to_byte
, from
, from_byte
))
1725 if (ret_string
|| ! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1726 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1730 /* Relocate all markers pointing into the new, larger gap
1731 to point at the end of the text before the gap.
1732 Do this before recording the deletion,
1733 so that undo handles this after reinserting the text. */
1734 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1736 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1737 record_delete (from
, deletion
);
1739 CHARS_MODIFF
= MODIFF
;
1741 /* Relocate point as if it were a marker. */
1743 adjust_point (from
- (PT
< to
? PT
: to
),
1744 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
1746 offset_intervals (current_buffer
, from
, - nchars_del
);
1748 /* Adjust the overlay center as needed. This must be done after
1749 adjusting the markers that bound the overlays. */
1750 adjust_overlays_for_delete (from
, nchars_del
);
1752 GAP_SIZE
+= nbytes_del
;
1753 ZV_BYTE
-= nbytes_del
;
1754 Z_BYTE
-= nbytes_del
;
1758 GPT_BYTE
= from_byte
;
1759 if (GAP_SIZE
> 0 && !current_buffer
->text
->inhibit_shrinking
)
1760 /* Put an anchor, unless called from decode_coding_object which
1761 needs to access the previous gap contents. */
1767 if (GPT
- BEG
< BEG_UNCHANGED
)
1768 BEG_UNCHANGED
= GPT
- BEG
;
1769 if (Z
- GPT
< END_UNCHANGED
)
1770 END_UNCHANGED
= Z
- GPT
;
1774 evaporate_overlays (from
);
1779 /* Call this if you're about to change the region of BUFFER from
1780 character positions START to END. This checks the read-only
1781 properties of the region, calls the necessary modification hooks,
1782 and warns the next redisplay that it should pay attention to that
1785 If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
1786 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1789 modify_region (struct buffer
*buffer
, ptrdiff_t start
, ptrdiff_t end
,
1790 int preserve_chars_modiff
)
1792 struct buffer
*old_buffer
= current_buffer
;
1794 if (buffer
!= old_buffer
)
1795 set_buffer_internal (buffer
);
1797 prepare_to_modify_buffer (start
, end
, NULL
);
1799 BUF_COMPUTE_UNCHANGED (buffer
, start
- 1, end
);
1801 if (MODIFF
<= SAVE_MODIFF
)
1802 record_first_change ();
1804 if (! preserve_chars_modiff
)
1805 CHARS_MODIFF
= MODIFF
;
1807 BVAR (buffer
, point_before_scroll
) = Qnil
;
1809 if (buffer
!= old_buffer
)
1810 set_buffer_internal (old_buffer
);
1813 /* Check that it is okay to modify the buffer between START and END,
1814 which are char positions.
1816 Run the before-change-function, if any. If intervals are in use,
1817 verify that the text to be modified is not read-only, and call
1818 any modification properties the text may have.
1820 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1821 by holding its value temporarily in a marker. */
1824 prepare_to_modify_buffer (ptrdiff_t start
, ptrdiff_t end
,
1825 ptrdiff_t *preserve_ptr
)
1827 struct buffer
*base_buffer
;
1829 if (!NILP (BVAR (current_buffer
, read_only
)))
1830 Fbarf_if_buffer_read_only ();
1832 /* Let redisplay consider other windows than selected_window
1833 if modifying another buffer. */
1834 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
1835 ++windows_or_buffers_changed
;
1837 if (BUF_INTERVALS (current_buffer
) != 0)
1841 Lisp_Object preserve_marker
;
1842 struct gcpro gcpro1
;
1843 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
1844 GCPRO1 (preserve_marker
);
1845 verify_interval_modification (current_buffer
, start
, end
);
1846 *preserve_ptr
= marker_position (preserve_marker
);
1847 unchain_marker (XMARKER (preserve_marker
));
1851 verify_interval_modification (current_buffer
, start
, end
);
1854 /* For indirect buffers, use the base buffer to check clashes. */
1855 if (current_buffer
->base_buffer
!= 0)
1856 base_buffer
= current_buffer
->base_buffer
;
1858 base_buffer
= current_buffer
;
1860 #ifdef CLASH_DETECTION
1861 if (!NILP (BVAR (base_buffer
, file_truename
))
1862 /* Make binding buffer-file-name to nil effective. */
1863 && !NILP (BVAR (base_buffer
, filename
))
1864 && SAVE_MODIFF
>= MODIFF
)
1865 lock_file (BVAR (base_buffer
, file_truename
));
1867 /* At least warn if this file has changed on disk since it was visited. */
1868 if (!NILP (BVAR (base_buffer
, filename
))
1869 && SAVE_MODIFF
>= MODIFF
1870 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
1871 && !NILP (Ffile_exists_p (BVAR (base_buffer
, filename
))))
1872 call1 (intern ("ask-user-about-supersession-threat"),
1873 BVAR (base_buffer
,filename
));
1874 #endif /* not CLASH_DETECTION */
1876 /* If `select-active-regions' is non-nil, save the region text. */
1877 if (!NILP (BVAR (current_buffer
, mark_active
))
1878 && !inhibit_modification_hooks
1879 && XMARKER (BVAR (current_buffer
, mark
))->buffer
1880 && NILP (Vsaved_region_selection
)
1881 && (EQ (Vselect_active_regions
, Qonly
)
1882 ? EQ (CAR_SAFE (Vtransient_mark_mode
), Qonly
)
1883 : (!NILP (Vselect_active_regions
)
1884 && !NILP (Vtransient_mark_mode
))))
1886 ptrdiff_t b
= XMARKER (BVAR (current_buffer
, mark
))->charpos
;
1889 Vsaved_region_selection
= make_buffer_string (b
, e
, 0);
1891 Vsaved_region_selection
= make_buffer_string (e
, b
, 0);
1894 signal_before_change (start
, end
, preserve_ptr
);
1896 if (current_buffer
->newline_cache
)
1897 invalidate_region_cache (current_buffer
,
1898 current_buffer
->newline_cache
,
1899 start
- BEG
, Z
- end
);
1900 if (current_buffer
->width_run_cache
)
1901 invalidate_region_cache (current_buffer
,
1902 current_buffer
->width_run_cache
,
1903 start
- BEG
, Z
- end
);
1905 Vdeactivate_mark
= Qt
;
1908 /* These macros work with an argument named `preserve_ptr'
1909 and a local variable named `preserve_marker'. */
1911 #define PRESERVE_VALUE \
1912 if (preserve_ptr && NILP (preserve_marker)) \
1913 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
1915 #define RESTORE_VALUE \
1916 if (! NILP (preserve_marker)) \
1918 *preserve_ptr = marker_position (preserve_marker); \
1919 unchain_marker (XMARKER (preserve_marker)); \
1922 #define PRESERVE_START_END \
1923 if (NILP (start_marker)) \
1924 start_marker = Fcopy_marker (start, Qnil); \
1925 if (NILP (end_marker)) \
1926 end_marker = Fcopy_marker (end, Qnil);
1928 #define FETCH_START \
1929 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
1932 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
1934 /* Set a variable to nil if an error occurred.
1935 Don't change the variable if there was no error.
1936 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
1937 VARIABLE is the variable to maybe set to nil.
1938 NO-ERROR-FLAG is nil if there was an error,
1939 anything else meaning no error (so this function does nothing). */
1941 reset_var_on_error (Lisp_Object val
)
1943 if (NILP (XCDR (val
)))
1944 Fset (XCAR (val
), Qnil
);
1948 /* Signal a change to the buffer immediately before it happens.
1949 START_INT and END_INT are the bounds of the text to be changed.
1951 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1952 by holding its value temporarily in a marker. */
1955 signal_before_change (ptrdiff_t start_int
, ptrdiff_t end_int
,
1956 ptrdiff_t *preserve_ptr
)
1958 Lisp_Object start
, end
;
1959 Lisp_Object start_marker
, end_marker
;
1960 Lisp_Object preserve_marker
;
1961 struct gcpro gcpro1
, gcpro2
, gcpro3
;
1962 ptrdiff_t count
= SPECPDL_INDEX ();
1964 if (inhibit_modification_hooks
)
1967 start
= make_number (start_int
);
1968 end
= make_number (end_int
);
1969 preserve_marker
= Qnil
;
1970 start_marker
= Qnil
;
1972 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
1974 specbind (Qinhibit_modification_hooks
, Qt
);
1976 /* If buffer is unmodified, run a special hook for that case. The
1977 check for Vfirst_change_hook is just a minor optimization. */
1978 if (SAVE_MODIFF
>= MODIFF
1979 && !NILP (Vfirst_change_hook
))
1983 Frun_hooks (1, &Qfirst_change_hook
);
1986 /* Now run the before-change-functions if any. */
1987 if (!NILP (Vbefore_change_functions
))
1989 Lisp_Object args
[3];
1990 Lisp_Object rvoe_arg
= Fcons (Qbefore_change_functions
, Qnil
);
1995 /* Mark before-change-functions to be reset to nil in case of error. */
1996 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
1998 /* Actually run the hook functions. */
1999 args
[0] = Qbefore_change_functions
;
2000 args
[1] = FETCH_START
;
2001 args
[2] = FETCH_END
;
2002 Frun_hook_with_args (3, args
);
2004 /* There was no error: unarm the reset_on_error. */
2005 XSETCDR (rvoe_arg
, Qt
);
2008 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2011 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2012 FETCH_START
, FETCH_END
, Qnil
);
2015 if (! NILP (start_marker
))
2016 free_marker (start_marker
);
2017 if (! NILP (end_marker
))
2018 free_marker (end_marker
);
2022 unbind_to (count
, Qnil
);
2025 /* Signal a change immediately after it happens.
2026 CHARPOS is the character position of the start of the changed text.
2027 LENDEL is the number of characters of the text before the change.
2028 (Not the whole buffer; just the part that was changed.)
2029 LENINS is the number of characters in that part of the text
2030 after the change. */
2033 signal_after_change (ptrdiff_t charpos
, ptrdiff_t lendel
, ptrdiff_t lenins
)
2035 ptrdiff_t count
= SPECPDL_INDEX ();
2036 if (inhibit_modification_hooks
)
2039 /* If we are deferring calls to the after-change functions
2040 and there are no before-change functions,
2041 just record the args that we were going to use. */
2042 if (! NILP (Vcombine_after_change_calls
)
2043 && NILP (Vbefore_change_functions
)
2044 && !current_buffer
->overlays_before
2045 && !current_buffer
->overlays_after
)
2049 if (!NILP (combine_after_change_list
)
2050 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2051 Fcombine_after_change_execute ();
2053 elt
= Fcons (make_number (charpos
- BEG
),
2054 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2055 Fcons (make_number (lenins
- lendel
), Qnil
)));
2056 combine_after_change_list
2057 = Fcons (elt
, combine_after_change_list
);
2058 combine_after_change_buffer
= Fcurrent_buffer ();
2063 if (!NILP (combine_after_change_list
))
2064 Fcombine_after_change_execute ();
2066 specbind (Qinhibit_modification_hooks
, Qt
);
2068 if (!NILP (Vafter_change_functions
))
2070 Lisp_Object args
[4];
2071 Lisp_Object rvoe_arg
= Fcons (Qafter_change_functions
, Qnil
);
2073 /* Mark after-change-functions to be reset to nil in case of error. */
2074 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2076 /* Actually run the hook functions. */
2077 args
[0] = Qafter_change_functions
;
2078 XSETFASTINT (args
[1], charpos
);
2079 XSETFASTINT (args
[2], charpos
+ lenins
);
2080 XSETFASTINT (args
[3], lendel
);
2081 Frun_hook_with_args (4, args
);
2083 /* There was no error: unarm the reset_on_error. */
2084 XSETCDR (rvoe_arg
, Qt
);
2087 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2088 report_overlay_modification (make_number (charpos
),
2089 make_number (charpos
+ lenins
),
2091 make_number (charpos
),
2092 make_number (charpos
+ lenins
),
2093 make_number (lendel
));
2095 /* After an insertion, call the text properties
2096 insert-behind-hooks or insert-in-front-hooks. */
2098 report_interval_modification (make_number (charpos
),
2099 make_number (charpos
+ lenins
));
2101 unbind_to (count
, Qnil
);
2105 Fcombine_after_change_execute_1 (Lisp_Object val
)
2107 Vcombine_after_change_calls
= val
;
2111 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2112 Scombine_after_change_execute
, 0, 0, 0,
2113 doc
: /* This function is for use internally in `combine-after-change-calls'. */)
2116 ptrdiff_t count
= SPECPDL_INDEX ();
2117 ptrdiff_t beg
, end
, change
;
2118 ptrdiff_t begpos
, endpos
;
2121 if (NILP (combine_after_change_list
))
2124 /* It is rare for combine_after_change_buffer to be invalid, but
2125 possible. It can happen when combine-after-change-calls is
2126 non-nil, and insertion calls a file handler (e.g. through
2127 lock_file) which scribbles into a temp file -- cyd */
2128 if (!BUFFERP (combine_after_change_buffer
)
2129 || NILP (BVAR (XBUFFER (combine_after_change_buffer
), name
)))
2131 combine_after_change_list
= Qnil
;
2135 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2137 Fset_buffer (combine_after_change_buffer
);
2139 /* # chars unchanged at beginning of buffer. */
2141 /* # chars unchanged at end of buffer. */
2143 /* Total amount of insertion (negative for deletion). */
2146 /* Scan the various individual changes,
2147 accumulating the range info in BEG, END and CHANGE. */
2148 for (tail
= combine_after_change_list
; CONSP (tail
);
2152 ptrdiff_t thisbeg
, thisend
, thischange
;
2154 /* Extract the info from the next element. */
2158 thisbeg
= XINT (XCAR (elt
));
2163 thisend
= XINT (XCAR (elt
));
2168 thischange
= XINT (XCAR (elt
));
2170 /* Merge this range into the accumulated range. */
2171 change
+= thischange
;
2178 /* Get the current start and end positions of the range
2179 that was changed. */
2183 /* We are about to handle these, so discard them. */
2184 combine_after_change_list
= Qnil
;
2186 /* Now run the after-change functions for real.
2187 Turn off the flag that defers them. */
2188 record_unwind_protect (Fcombine_after_change_execute_1
,
2189 Vcombine_after_change_calls
);
2190 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2191 update_compositions (begpos
, endpos
, CHECK_ALL
);
2193 return unbind_to (count
, Qnil
);
2197 syms_of_insdel (void)
2199 staticpro (&combine_after_change_list
);
2200 staticpro (&combine_after_change_buffer
);
2201 combine_after_change_list
= Qnil
;
2202 combine_after_change_buffer
= Qnil
;
2204 DEFVAR_BOOL ("check-markers-debug-flag", check_markers_debug_flag
,
2205 doc
: /* Non-nil means enable debugging checks for invalid marker positions. */);
2206 check_markers_debug_flag
= 0;
2207 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls
,
2208 doc
: /* Used internally by the `combine-after-change-calls' macro. */);
2209 Vcombine_after_change_calls
= Qnil
;
2211 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks
,
2212 doc
: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2213 This affects `before-change-functions' and `after-change-functions',
2214 as well as hooks attached to text properties and overlays. */);
2215 inhibit_modification_hooks
= 0;
2216 DEFSYM (Qinhibit_modification_hooks
, "inhibit-modification-hooks");
2218 defsubr (&Scombine_after_change_execute
);