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"
29 #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 static Lisp_Object
Fcombine_after_change_execute (void);
46 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
47 describing changes which happened while combine_after_change_calls
48 was nonzero. We use this to decide how to call them
49 once the deferral ends.
52 BEG-UNCHANGED is the number of chars before the changed range.
53 END-UNCHANGED is the number of chars after the changed range,
54 and CHANGE-AMOUNT is the number of characters inserted by the change
55 (negative for a deletion). */
56 static Lisp_Object combine_after_change_list
;
58 /* Buffer which combine_after_change_list is about. */
59 static Lisp_Object combine_after_change_buffer
;
61 Lisp_Object Qinhibit_modification_hooks
;
63 static void signal_before_change (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
65 #define CHECK_MARKERS() \
68 if (check_markers_debug_flag) \
76 register struct Lisp_Marker
*tail
;
77 int multibyte
= ! NILP (BVAR (current_buffer
, enable_multibyte_characters
));
79 for (tail
= BUF_MARKERS (current_buffer
); tail
; tail
= tail
->next
)
81 if (tail
->buffer
->text
!= current_buffer
->text
)
83 if (tail
->charpos
> Z
)
85 if (tail
->bytepos
> Z_BYTE
)
87 if (multibyte
&& ! CHAR_HEAD_P (FETCH_BYTE (tail
->bytepos
)))
92 /* Move gap to position CHARPOS.
93 Note that this can quit! */
96 move_gap (ptrdiff_t charpos
)
98 move_gap_both (charpos
, charpos_to_bytepos (charpos
));
101 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
102 Note that this can quit! */
105 move_gap_both (ptrdiff_t charpos
, ptrdiff_t bytepos
)
107 if (bytepos
< GPT_BYTE
)
108 gap_left (charpos
, bytepos
, 0);
109 else if (bytepos
> GPT_BYTE
)
110 gap_right (charpos
, bytepos
);
113 /* Move the gap to a position less than the current GPT.
114 BYTEPOS describes the new position as a byte position,
115 and CHARPOS is the corresponding char position.
116 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
119 gap_left (ptrdiff_t charpos
, ptrdiff_t bytepos
, int newgap
)
121 register unsigned char *to
, *from
;
122 register ptrdiff_t i
;
126 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
133 /* Now copy the characters. To move the gap down,
134 copy characters up. */
138 /* I gets number of characters left to copy. */
139 i
= new_s1
- bytepos
;
142 /* If a quit is requested, stop copying now.
143 Change BYTEPOS to be where we have actually moved the gap to. */
147 charpos
= BYTE_TO_CHAR (bytepos
);
150 /* Move at most 32000 chars before checking again for a quit. */
155 memmove (to
, from
, i
);
158 /* Adjust buffer data structure, to put the gap at BYTEPOS.
159 BYTEPOS is where the loop above stopped, which may be what
160 was specified or may be where a quit was detected. */
163 if (bytepos
< charpos
)
165 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
169 /* Move the gap to a position greater than the current GPT.
170 BYTEPOS describes the new position as a byte position,
171 and CHARPOS is the corresponding char position. */
174 gap_right (ptrdiff_t charpos
, ptrdiff_t bytepos
)
176 register unsigned char *to
, *from
;
177 register ptrdiff_t i
;
180 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
187 /* Now copy the characters. To move the gap up,
188 copy characters down. */
192 /* I gets number of characters left to copy. */
193 i
= bytepos
- new_s1
;
196 /* If a quit is requested, stop copying now.
197 Change BYTEPOS to be where we have actually moved the gap to. */
201 charpos
= BYTE_TO_CHAR (bytepos
);
204 /* Move at most 32000 chars before checking again for a quit. */
208 memmove (to
, from
, i
);
214 if (bytepos
< charpos
)
216 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
220 /* Adjust all markers for a deletion
221 whose range in bytes is FROM_BYTE to TO_BYTE.
222 The range in charpos is FROM to TO.
224 This function assumes that the gap is adjacent to
225 or inside of the range being deleted. */
228 adjust_markers_for_delete (ptrdiff_t from
, ptrdiff_t from_byte
,
229 ptrdiff_t to
, ptrdiff_t to_byte
)
232 register struct Lisp_Marker
*m
;
233 register ptrdiff_t charpos
;
235 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
237 charpos
= m
->charpos
;
242 /* If the marker is after the deletion,
243 relocate by number of chars / bytes deleted. */
246 m
->charpos
-= to
- from
;
247 m
->bytepos
-= to_byte
- from_byte
;
249 /* Here's the case where a marker is inside text being deleted. */
250 else if (charpos
> from
)
252 if (! m
->insertion_type
)
253 { /* Normal markers will end up at the beginning of the
254 re-inserted text after undoing a deletion, and must be
255 adjusted to move them to the correct place. */
256 XSETMISC (marker
, m
);
257 record_marker_adjustment (marker
, from
- charpos
);
259 else if (charpos
< to
)
260 { /* Before-insertion markers will automatically move forward
261 upon re-inserting the deleted text, so we have to arrange
262 for them to move backward to the correct position. */
263 XSETMISC (marker
, m
);
264 record_marker_adjustment (marker
, to
- charpos
);
267 m
->bytepos
= from_byte
;
269 /* Here's the case where a before-insertion marker is immediately
270 before the deleted region. */
271 else if (charpos
== from
&& m
->insertion_type
)
273 /* Undoing the change uses normal insertion, which will
274 incorrectly make MARKER move forward, so we arrange for it
275 to then move backward to the correct place at the beginning
276 of the deleted region. */
277 XSETMISC (marker
, m
);
278 record_marker_adjustment (marker
, to
- from
);
284 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
285 to TO / TO_BYTE. We have to relocate the charpos of every marker
286 that points after the insertion (but not their bytepos).
288 When a marker points at the insertion point,
289 we advance it if either its insertion-type is t
290 or BEFORE_MARKERS is true. */
293 adjust_markers_for_insert (ptrdiff_t from
, ptrdiff_t from_byte
,
294 ptrdiff_t to
, ptrdiff_t to_byte
, int before_markers
)
296 struct Lisp_Marker
*m
;
298 ptrdiff_t nchars
= to
- from
;
299 ptrdiff_t nbytes
= to_byte
- from_byte
;
301 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
303 eassert (m
->bytepos
>= m
->charpos
304 && m
->bytepos
- m
->charpos
<= Z_BYTE
- Z
);
306 if (m
->bytepos
== from_byte
)
308 if (m
->insertion_type
|| before_markers
)
310 m
->bytepos
= to_byte
;
312 if (m
->insertion_type
)
316 else if (m
->bytepos
> from_byte
)
318 m
->bytepos
+= nbytes
;
319 m
->charpos
+= nchars
;
323 /* Adjusting only markers whose insertion-type is t may result in
324 - disordered start and end in overlays, and
325 - disordered overlays in the slot `overlays_before' of current_buffer. */
328 fix_start_end_in_overlays (from
, to
);
329 fix_overlays_before (current_buffer
, from
, to
);
333 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
335 This is used only when the value of point changes due to an insert
336 or delete; it does not represent a conceptual change in point as a
337 marker. In particular, point is not crossing any interval
338 boundaries, so there's no need to use the usual SET_PT macro. In
339 fact it would be incorrect to do so, because either the old or the
340 new value of point is out of sync with the current set of
344 adjust_point (ptrdiff_t nchars
, ptrdiff_t nbytes
)
346 SET_BUF_PT_BOTH (current_buffer
, PT
+ nchars
, PT_BYTE
+ nbytes
);
347 /* In a single-byte buffer, the two positions must be equal. */
348 eassert (PT_BYTE
>= PT
&& PT_BYTE
- PT
<= ZV_BYTE
- ZV
);
351 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
352 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
353 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
357 adjust_markers_for_replace (ptrdiff_t from
, ptrdiff_t from_byte
,
358 ptrdiff_t old_chars
, ptrdiff_t old_bytes
,
359 ptrdiff_t new_chars
, ptrdiff_t new_bytes
)
361 register struct Lisp_Marker
*m
;
362 ptrdiff_t prev_to_byte
= from_byte
+ old_bytes
;
363 ptrdiff_t diff_chars
= new_chars
- old_chars
;
364 ptrdiff_t diff_bytes
= new_bytes
- old_bytes
;
366 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
368 if (m
->bytepos
>= prev_to_byte
)
370 m
->charpos
+= diff_chars
;
371 m
->bytepos
+= diff_bytes
;
373 else if (m
->bytepos
> from_byte
)
376 m
->bytepos
= from_byte
;
385 buffer_overflow (void)
387 error ("Maximum buffer size exceeded");
390 /* Make the gap NBYTES_ADDED bytes longer. */
393 make_gap_larger (ptrdiff_t nbytes_added
)
396 ptrdiff_t real_gap_loc
;
397 ptrdiff_t real_gap_loc_byte
;
398 ptrdiff_t old_gap_size
;
399 ptrdiff_t current_size
= Z_BYTE
- BEG_BYTE
+ GAP_SIZE
;
400 enum { enough_for_a_while
= 2000 };
402 if (BUF_BYTES_MAX
- current_size
< nbytes_added
)
405 /* If we have to get more space, get enough to last a while;
406 but do not exceed the maximum buffer size. */
407 nbytes_added
= min (nbytes_added
+ enough_for_a_while
,
408 BUF_BYTES_MAX
- current_size
);
410 enlarge_buffer_text (current_buffer
, nbytes_added
);
412 /* Prevent quitting in move_gap. */
417 real_gap_loc_byte
= GPT_BYTE
;
418 old_gap_size
= GAP_SIZE
;
420 /* Call the newly allocated space a gap at the end of the whole space. */
422 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
423 GAP_SIZE
= nbytes_added
;
425 /* Move the new gap down to be consecutive with the end of the old one.
426 This adjusts the markers properly too. */
427 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
429 /* Now combine the two into one large gap. */
430 GAP_SIZE
+= old_gap_size
;
432 GPT_BYTE
= real_gap_loc_byte
;
440 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
442 /* Make the gap NBYTES_REMOVED bytes shorter. */
445 make_gap_smaller (ptrdiff_t nbytes_removed
)
448 ptrdiff_t real_gap_loc
;
449 ptrdiff_t real_gap_loc_byte
;
451 ptrdiff_t real_Z_byte
;
452 ptrdiff_t real_beg_unchanged
;
453 ptrdiff_t new_gap_size
;
455 /* Make sure the gap is at least 20 bytes. */
456 if (GAP_SIZE
- nbytes_removed
< 20)
457 nbytes_removed
= GAP_SIZE
- 20;
459 /* Prevent quitting in move_gap. */
464 real_gap_loc_byte
= GPT_BYTE
;
465 new_gap_size
= GAP_SIZE
- nbytes_removed
;
467 real_Z_byte
= Z_BYTE
;
468 real_beg_unchanged
= BEG_UNCHANGED
;
470 /* Pretend that the last unwanted part of the gap is the entire gap,
471 and that the first desired part of the gap is part of the buffer
473 memset (GPT_ADDR
, 0, new_gap_size
);
475 GPT_BYTE
+= new_gap_size
;
477 Z_BYTE
+= new_gap_size
;
478 GAP_SIZE
= nbytes_removed
;
480 /* Move the unwanted pretend gap to the end of the buffer. This
481 adjusts the markers properly too. */
482 gap_right (Z
, Z_BYTE
);
484 enlarge_buffer_text (current_buffer
, -nbytes_removed
);
486 /* Now restore the desired gap. */
487 GAP_SIZE
= new_gap_size
;
489 GPT_BYTE
= real_gap_loc_byte
;
491 Z_BYTE
= real_Z_byte
;
492 BEG_UNCHANGED
= real_beg_unchanged
;
500 #endif /* USE_MMAP_FOR_BUFFERS || REL_ALLOC || DOUG_LEA_MALLOC */
503 make_gap (ptrdiff_t nbytes_added
)
505 if (nbytes_added
>= 0)
506 make_gap_larger (nbytes_added
);
507 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
509 make_gap_smaller (-nbytes_added
);
513 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
514 FROM_MULTIBYTE says whether the incoming text is multibyte.
515 TO_MULTIBYTE says whether to store the text as multibyte.
516 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
518 Return the number of bytes stored at TO_ADDR. */
521 copy_text (const unsigned char *from_addr
, unsigned char *to_addr
,
522 ptrdiff_t nbytes
, int from_multibyte
, int to_multibyte
)
524 if (from_multibyte
== to_multibyte
)
526 memcpy (to_addr
, from_addr
, nbytes
);
529 else if (from_multibyte
)
531 ptrdiff_t nchars
= 0;
532 ptrdiff_t bytes_left
= nbytes
;
534 while (bytes_left
> 0)
537 c
= STRING_CHAR_AND_LENGTH (from_addr
, thislen
);
538 if (! ASCII_CHAR_P (c
))
541 from_addr
+= thislen
;
542 bytes_left
-= thislen
;
549 unsigned char *initial_to_addr
= to_addr
;
551 /* Convert single-byte to multibyte. */
554 int c
= *from_addr
++;
556 if (!ASCII_CHAR_P (c
))
558 c
= BYTE8_TO_CHAR (c
);
559 to_addr
+= CHAR_STRING (c
, to_addr
);
563 /* Special case for speed. */
564 *to_addr
++ = c
, nbytes
--;
566 return to_addr
- initial_to_addr
;
570 /* Insert a string of specified length before point.
571 This function judges multibyteness based on
572 enable_multibyte_characters in the current buffer;
573 it never converts between single-byte and multibyte.
575 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
576 prepare_to_modify_buffer could relocate the text. */
579 insert (const char *string
, ptrdiff_t nbytes
)
583 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
584 insert_1_both (string
, len
, nbytes
, 0, 1, 0);
586 signal_after_change (opoint
, 0, len
);
587 update_compositions (opoint
, PT
, CHECK_BORDER
);
591 /* Likewise, but inherit text properties from neighboring characters. */
594 insert_and_inherit (const char *string
, ptrdiff_t nbytes
)
598 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
599 insert_1_both (string
, len
, nbytes
, 1, 1, 0);
601 signal_after_change (opoint
, 0, len
);
602 update_compositions (opoint
, PT
, CHECK_BORDER
);
606 /* Insert the character C before point. Do not inherit text properties. */
611 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
614 if (! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
615 len
= CHAR_STRING (c
, str
);
622 insert ((char *) str
, len
);
625 /* Insert the null-terminated string S before point. */
628 insert_string (const char *s
)
630 insert (s
, strlen (s
));
633 /* Like `insert' except that all markers pointing at the place where
634 the insertion happens are adjusted to point after it.
635 Don't use this function to insert part of a Lisp string,
636 since gc could happen and relocate it. */
639 insert_before_markers (const char *string
, ptrdiff_t nbytes
)
643 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
644 insert_1_both (string
, len
, nbytes
, 0, 1, 1);
646 signal_after_change (opoint
, 0, len
);
647 update_compositions (opoint
, PT
, CHECK_BORDER
);
651 /* Likewise, but inherit text properties from neighboring characters. */
654 insert_before_markers_and_inherit (const char *string
,
659 ptrdiff_t len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
660 insert_1_both (string
, len
, nbytes
, 1, 1, 1);
662 signal_after_change (opoint
, 0, len
);
663 update_compositions (opoint
, PT
, CHECK_BORDER
);
667 /* Subroutine used by the insert functions above. */
670 insert_1 (const char *string
, ptrdiff_t nbytes
,
671 int inherit
, int prepare
, int before_markers
)
673 insert_1_both (string
, chars_in_text ((unsigned char *) string
, nbytes
),
674 nbytes
, inherit
, prepare
, before_markers
);
678 #ifdef BYTE_COMBINING_DEBUG
680 /* See if the bytes before POS/POS_BYTE combine with bytes
681 at the start of STRING to form a single character.
682 If so, return the number of bytes at the start of STRING
683 which combine in this way. Otherwise, return 0. */
686 count_combining_before (const unsigned char *string
, ptrdiff_t length
,
687 ptrdiff_t pos
, ptrdiff_t pos_byte
)
689 int len
, combining_bytes
;
690 const unsigned char *p
;
692 if (NILP (current_buffer
->enable_multibyte_characters
))
695 /* At first, we can exclude the following cases:
696 (1) STRING[0] can't be a following byte of multibyte sequence.
697 (2) POS is the start of the current buffer.
698 (3) A character before POS is not a multibyte character. */
699 if (length
== 0 || CHAR_HEAD_P (*string
)) /* case (1) */
701 if (pos_byte
== BEG_BYTE
) /* case (2) */
704 p
= BYTE_POS_ADDR (pos_byte
- 1);
705 while (! CHAR_HEAD_P (*p
)) p
--, len
++;
706 if (! LEADING_CODE_P (*p
)) /* case (3) */
709 combining_bytes
= BYTES_BY_CHAR_HEAD (*p
) - len
;
710 if (combining_bytes
<= 0)
711 /* The character preceding POS is, complete and no room for
712 combining bytes (combining_bytes == 0), or an independent 8-bit
713 character (combining_bytes < 0). */
716 /* We have a combination situation. Count the bytes at STRING that
719 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
722 return (combining_bytes
< p
- string
? combining_bytes
: p
- string
);
725 /* See if the bytes after POS/POS_BYTE combine with bytes
726 at the end of STRING to form a single character.
727 If so, return the number of bytes after POS/POS_BYTE
728 which combine in this way. Otherwise, return 0. */
731 count_combining_after (const unsigned char *string
,
732 ptrdiff_t length
, ptrdiff_t pos
, ptrdiff_t pos_byte
)
734 ptrdiff_t opos_byte
= pos_byte
;
739 if (NILP (current_buffer
->enable_multibyte_characters
))
742 /* At first, we can exclude the following cases:
743 (1) The last byte of STRING is an ASCII.
744 (2) POS is the last of the current buffer.
745 (3) A character at POS can't be a following byte of multibyte
747 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1])) /* case (1) */
749 if (pos_byte
== Z_BYTE
) /* case (2) */
751 bufp
= BYTE_POS_ADDR (pos_byte
);
752 if (CHAR_HEAD_P (*bufp
)) /* case (3) */
756 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
762 /* All characters in STRING are not character head. We must
763 check also preceding bytes at POS. We are sure that the gap
765 unsigned char *p
= BEG_ADDR
;
767 while (i
>= 0 && ! CHAR_HEAD_P (p
[i
]))
769 if (i
< 0 || !LEADING_CODE_P (p
[i
]))
772 bytes
= BYTES_BY_CHAR_HEAD (p
[i
]);
773 return (bytes
<= pos_byte
- 1 - i
+ length
775 : bytes
- (pos_byte
- 1 - i
+ length
));
777 if (!LEADING_CODE_P (string
[i
]))
780 bytes
= BYTES_BY_CHAR_HEAD (string
[i
]) - (length
- i
);
782 while (!CHAR_HEAD_P (*bufp
)) bufp
++, pos_byte
++;
784 return (bytes
<= pos_byte
- opos_byte
? bytes
: pos_byte
- opos_byte
);
790 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
791 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
792 are the same as in insert_1. */
795 insert_1_both (const char *string
,
796 ptrdiff_t nchars
, ptrdiff_t nbytes
,
797 int inherit
, int prepare
, int before_markers
)
802 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
806 /* Do this before moving and increasing the gap,
807 because the before-change hooks might move the gap
808 or make it smaller. */
809 prepare_to_modify_buffer (PT
, PT
, NULL
);
812 move_gap_both (PT
, PT_BYTE
);
813 if (GAP_SIZE
< nbytes
)
814 make_gap (nbytes
- GAP_SIZE
);
816 #ifdef BYTE_COMBINING_DEBUG
817 if (count_combining_before (string
, nbytes
, PT
, PT_BYTE
)
818 || count_combining_after (string
, nbytes
, PT
, PT_BYTE
))
822 /* Record deletion of the surrounding text that combines with
823 the insertion. This, together with recording the insertion,
824 will add up to the right stuff in the undo list. */
825 record_insert (PT
, nchars
);
827 CHARS_MODIFF
= MODIFF
;
829 memcpy (GPT_ADDR
, string
, nbytes
);
838 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
843 /* The insert may have been in the unchanged region, so check again. */
844 if (Z
- GPT
< END_UNCHANGED
)
845 END_UNCHANGED
= Z
- GPT
;
847 adjust_overlays_for_insert (PT
, nchars
);
848 adjust_markers_for_insert (PT
, PT_BYTE
,
849 PT
+ nchars
, PT_BYTE
+ nbytes
,
852 if (BUF_INTERVALS (current_buffer
) != 0)
853 offset_intervals (current_buffer
, PT
, nchars
);
855 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
856 set_text_properties (make_number (PT
), make_number (PT
+ nchars
),
859 adjust_point (nchars
, nbytes
);
864 /* Insert the part of the text of STRING, a Lisp object assumed to be
865 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
866 starting at position POS / POS_BYTE. If the text of STRING has properties,
867 copy them into the buffer.
869 It does not work to use `insert' for this, because a GC could happen
870 before we copy the stuff into the buffer, and relocate the string
871 without insert noticing. */
874 insert_from_string (Lisp_Object string
, ptrdiff_t pos
, ptrdiff_t pos_byte
,
875 ptrdiff_t length
, ptrdiff_t length_byte
, int inherit
)
877 ptrdiff_t opoint
= PT
;
879 if (SCHARS (string
) == 0)
882 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
884 signal_after_change (opoint
, 0, PT
- opoint
);
885 update_compositions (opoint
, PT
, CHECK_BORDER
);
888 /* Like `insert_from_string' except that all markers pointing
889 at the place where the insertion happens are adjusted to point after it. */
892 insert_from_string_before_markers (Lisp_Object string
,
893 ptrdiff_t pos
, ptrdiff_t pos_byte
,
894 ptrdiff_t length
, ptrdiff_t length_byte
,
897 ptrdiff_t opoint
= PT
;
899 if (SCHARS (string
) == 0)
902 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
904 signal_after_change (opoint
, 0, PT
- opoint
);
905 update_compositions (opoint
, PT
, CHECK_BORDER
);
908 /* Subroutine of the insertion functions above. */
911 insert_from_string_1 (Lisp_Object string
, ptrdiff_t pos
, ptrdiff_t pos_byte
,
912 ptrdiff_t nchars
, ptrdiff_t nbytes
,
913 int inherit
, int before_markers
)
916 ptrdiff_t outgoing_nbytes
= nbytes
;
919 /* Make OUTGOING_NBYTES describe the text
920 as it will be inserted in this buffer. */
922 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
923 outgoing_nbytes
= nchars
;
924 else if (! STRING_MULTIBYTE (string
))
926 = count_size_as_multibyte (SDATA (string
) + pos_byte
,
930 /* Do this before moving and increasing the gap,
931 because the before-change hooks might move the gap
932 or make it smaller. */
933 prepare_to_modify_buffer (PT
, PT
, NULL
);
936 move_gap_both (PT
, PT_BYTE
);
937 if (GAP_SIZE
< outgoing_nbytes
)
938 make_gap (outgoing_nbytes
- GAP_SIZE
);
941 /* Copy the string text into the buffer, perhaps converting
942 between single-byte and multibyte. */
943 copy_text (SDATA (string
) + pos_byte
, GPT_ADDR
, nbytes
,
944 STRING_MULTIBYTE (string
),
945 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
947 #ifdef BYTE_COMBINING_DEBUG
948 /* We have copied text into the gap, but we have not altered
949 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
950 to these functions and get the same results as we would
951 have got earlier on. Meanwhile, PT_ADDR does point to
952 the text that has been stored by copy_text. */
953 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
954 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
958 record_insert (PT
, nchars
);
960 CHARS_MODIFF
= MODIFF
;
962 GAP_SIZE
-= outgoing_nbytes
;
966 GPT_BYTE
+= outgoing_nbytes
;
967 ZV_BYTE
+= outgoing_nbytes
;
968 Z_BYTE
+= outgoing_nbytes
;
969 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
974 /* The insert may have been in the unchanged region, so check again. */
975 if (Z
- GPT
< END_UNCHANGED
)
976 END_UNCHANGED
= Z
- GPT
;
978 adjust_overlays_for_insert (PT
, nchars
);
979 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
980 PT_BYTE
+ outgoing_nbytes
,
983 offset_intervals (current_buffer
, PT
, nchars
);
985 intervals
= STRING_INTERVALS (string
);
986 /* Get the intervals for the part of the string we are inserting. */
987 if (nbytes
< SBYTES (string
))
988 intervals
= copy_intervals (intervals
, pos
, nchars
);
990 /* Insert those intervals. */
991 graft_intervals_into_buffer (intervals
, PT
, nchars
,
992 current_buffer
, inherit
);
994 adjust_point (nchars
, outgoing_nbytes
);
999 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1000 starting at GPT_ADDR. */
1003 insert_from_gap (ptrdiff_t nchars
, ptrdiff_t nbytes
)
1005 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1008 record_insert (GPT
, nchars
);
1018 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1023 adjust_overlays_for_insert (GPT
- nchars
, nchars
);
1024 adjust_markers_for_insert (GPT
- nchars
, GPT_BYTE
- nbytes
,
1027 if (BUF_INTERVALS (current_buffer
) != 0)
1029 offset_intervals (current_buffer
, GPT
- nchars
, nchars
);
1030 graft_intervals_into_buffer (NULL_INTERVAL
, GPT
- nchars
, nchars
,
1034 if (GPT
- nchars
< PT
)
1035 adjust_point (nchars
, nbytes
);
1040 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1041 current buffer. If the text in BUF has properties, they are absorbed
1042 into the current buffer.
1044 It does not work to use `insert' for this, because a malloc could happen
1045 and relocate BUF's text before the copy happens. */
1048 insert_from_buffer (struct buffer
*buf
,
1049 ptrdiff_t charpos
, ptrdiff_t nchars
, int inherit
)
1051 ptrdiff_t opoint
= PT
;
1053 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1054 signal_after_change (opoint
, 0, PT
- opoint
);
1055 update_compositions (opoint
, PT
, CHECK_BORDER
);
1059 insert_from_buffer_1 (struct buffer
*buf
,
1060 ptrdiff_t from
, ptrdiff_t nchars
, int inherit
)
1062 ptrdiff_t chunk
, chunk_expanded
;
1063 ptrdiff_t from_byte
= buf_charpos_to_bytepos (buf
, from
);
1064 ptrdiff_t to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1065 ptrdiff_t incoming_nbytes
= to_byte
- from_byte
;
1066 ptrdiff_t outgoing_nbytes
= incoming_nbytes
;
1069 /* Make OUTGOING_NBYTES describe the text
1070 as it will be inserted in this buffer. */
1072 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1073 outgoing_nbytes
= nchars
;
1074 else if (NILP (BVAR (buf
, enable_multibyte_characters
)))
1076 ptrdiff_t outgoing_before_gap
= 0;
1077 ptrdiff_t outgoing_after_gap
= 0;
1079 if (from
< BUF_GPT (buf
))
1081 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1082 if (chunk
> incoming_nbytes
)
1083 chunk
= incoming_nbytes
;
1085 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1091 if (chunk
< incoming_nbytes
)
1093 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
,
1095 incoming_nbytes
- chunk
);
1097 outgoing_nbytes
= outgoing_before_gap
+ outgoing_after_gap
;
1100 /* Do this before moving and increasing the gap,
1101 because the before-change hooks might move the gap
1102 or make it smaller. */
1103 prepare_to_modify_buffer (PT
, PT
, NULL
);
1106 move_gap_both (PT
, PT_BYTE
);
1107 if (GAP_SIZE
< outgoing_nbytes
)
1108 make_gap (outgoing_nbytes
- GAP_SIZE
);
1110 if (from
< BUF_GPT (buf
))
1112 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1113 if (chunk
> incoming_nbytes
)
1114 chunk
= incoming_nbytes
;
1115 /* Record number of output bytes, so we know where
1116 to put the output from the second copy_text. */
1118 = copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1120 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1121 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1124 chunk_expanded
= chunk
= 0;
1126 if (chunk
< incoming_nbytes
)
1127 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1128 GPT_ADDR
+ chunk_expanded
, incoming_nbytes
- chunk
,
1129 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1130 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1132 #ifdef BYTE_COMBINING_DEBUG
1133 /* We have copied text into the gap, but we have not altered
1134 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1135 to these functions and get the same results as we would
1136 have got earlier on. Meanwhile, GPT_ADDR does point to
1137 the text that has been stored by copy_text. */
1138 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1139 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1143 record_insert (PT
, nchars
);
1145 CHARS_MODIFF
= MODIFF
;
1147 GAP_SIZE
-= outgoing_nbytes
;
1151 GPT_BYTE
+= outgoing_nbytes
;
1152 ZV_BYTE
+= outgoing_nbytes
;
1153 Z_BYTE
+= outgoing_nbytes
;
1154 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1159 /* The insert may have been in the unchanged region, so check again. */
1160 if (Z
- GPT
< END_UNCHANGED
)
1161 END_UNCHANGED
= Z
- GPT
;
1163 adjust_overlays_for_insert (PT
, nchars
);
1164 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1165 PT_BYTE
+ outgoing_nbytes
,
1168 if (BUF_INTERVALS (current_buffer
) != 0)
1169 offset_intervals (current_buffer
, PT
, nchars
);
1171 /* Get the intervals for the part of the string we are inserting. */
1172 intervals
= BUF_INTERVALS (buf
);
1173 if (nchars
< BUF_Z (buf
) - BUF_BEG (buf
))
1175 if (buf
== current_buffer
&& PT
<= from
)
1177 intervals
= copy_intervals (intervals
, from
, nchars
);
1180 /* Insert those intervals. */
1181 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1183 adjust_point (nchars
, outgoing_nbytes
);
1186 /* Record undo information and adjust markers and position keepers for
1187 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1188 chars (LEN_BYTE bytes) which resides in the gap just after
1191 PREV_TEXT nil means the new text was just inserted. */
1194 adjust_after_replace (ptrdiff_t from
, ptrdiff_t from_byte
,
1195 Lisp_Object prev_text
, ptrdiff_t len
, ptrdiff_t len_byte
)
1197 ptrdiff_t nchars_del
= 0, nbytes_del
= 0;
1199 #ifdef BYTE_COMBINING_DEBUG
1200 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1201 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1205 if (STRINGP (prev_text
))
1207 nchars_del
= SCHARS (prev_text
);
1208 nbytes_del
= SBYTES (prev_text
);
1211 /* Update various buffer positions for the new text. */
1212 GAP_SIZE
-= len_byte
;
1214 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1215 GPT
+= len
; GPT_BYTE
+= len_byte
;
1216 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1219 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1222 adjust_markers_for_insert (from
, from_byte
,
1223 from
+ len
, from_byte
+ len_byte
, 0);
1225 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1228 record_delete (from
, prev_text
);
1229 record_insert (from
, len
);
1232 if (len
> nchars_del
)
1233 adjust_overlays_for_insert (from
, len
- nchars_del
);
1234 else if (len
< nchars_del
)
1235 adjust_overlays_for_delete (from
, nchars_del
- len
);
1236 if (BUF_INTERVALS (current_buffer
) != 0)
1238 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1242 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1244 /* As byte combining will decrease Z, we must check this again. */
1245 if (Z
- GPT
< END_UNCHANGED
)
1246 END_UNCHANGED
= Z
- GPT
;
1251 evaporate_overlays (from
);
1253 CHARS_MODIFF
= MODIFF
;
1256 /* Record undo information, adjust markers and position keepers for an
1257 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1258 text already exists in the current buffer but character length (TO
1259 - FROM) may be incorrect, the correct length is NEWLEN. */
1262 adjust_after_insert (ptrdiff_t from
, ptrdiff_t from_byte
,
1263 ptrdiff_t to
, ptrdiff_t to_byte
, ptrdiff_t newlen
)
1265 ptrdiff_t len
= to
- from
, len_byte
= to_byte
- from_byte
;
1268 move_gap_both (to
, to_byte
);
1269 GAP_SIZE
+= len_byte
;
1270 GPT
-= len
; GPT_BYTE
-= len_byte
;
1271 ZV
-= len
; ZV_BYTE
-= len_byte
;
1272 Z
-= len
; Z_BYTE
-= len_byte
;
1273 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1276 /* Replace the text from character positions FROM to TO with NEW,
1277 If PREPARE is nonzero, call prepare_to_modify_buffer.
1278 If INHERIT, the newly inserted text should inherit text properties
1279 from the surrounding non-deleted text. */
1281 /* Note that this does not yet handle markers quite right.
1282 Also it needs to record a single undo-entry that does a replacement
1283 rather than a separate delete and insert.
1284 That way, undo will also handle markers properly.
1286 But if MARKERS is 0, don't relocate markers. */
1289 replace_range (ptrdiff_t from
, ptrdiff_t to
, Lisp_Object
new,
1290 int prepare
, int inherit
, int markers
)
1292 ptrdiff_t inschars
= SCHARS (new);
1293 ptrdiff_t insbytes
= SBYTES (new);
1294 ptrdiff_t from_byte
, to_byte
;
1295 ptrdiff_t nbytes_del
, nchars_del
;
1296 struct gcpro gcpro1
;
1298 ptrdiff_t outgoing_insbytes
= insbytes
;
1299 Lisp_Object deletion
;
1308 ptrdiff_t range_length
= to
- from
;
1309 prepare_to_modify_buffer (from
, to
, &from
);
1310 to
= from
+ range_length
;
1315 /* Make args be valid. */
1321 from_byte
= CHAR_TO_BYTE (from
);
1322 to_byte
= CHAR_TO_BYTE (to
);
1324 nchars_del
= to
- from
;
1325 nbytes_del
= to_byte
- from_byte
;
1327 if (nbytes_del
<= 0 && insbytes
== 0)
1330 /* Make OUTGOING_INSBYTES describe the text
1331 as it will be inserted in this buffer. */
1333 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1334 outgoing_insbytes
= inschars
;
1335 else if (! STRING_MULTIBYTE (new))
1337 = count_size_as_multibyte (SDATA (new), insbytes
);
1341 /* Make sure the gap is somewhere in or next to what we are deleting. */
1343 gap_right (from
, from_byte
);
1345 gap_left (to
, to_byte
, 0);
1347 /* Even if we don't record for undo, we must keep the original text
1348 because we may have to recover it because of inappropriate byte
1350 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1351 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1353 GAP_SIZE
+= nbytes_del
;
1356 ZV_BYTE
-= nbytes_del
;
1357 Z_BYTE
-= nbytes_del
;
1359 GPT_BYTE
= from_byte
;
1360 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1365 if (GPT
- BEG
< BEG_UNCHANGED
)
1366 BEG_UNCHANGED
= GPT
- BEG
;
1367 if (Z
- GPT
< END_UNCHANGED
)
1368 END_UNCHANGED
= Z
- GPT
;
1370 if (GAP_SIZE
< outgoing_insbytes
)
1371 make_gap (outgoing_insbytes
- GAP_SIZE
);
1373 /* Copy the string text into the buffer, perhaps converting
1374 between single-byte and multibyte. */
1375 copy_text (SDATA (new), GPT_ADDR
, insbytes
,
1376 STRING_MULTIBYTE (new),
1377 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1379 #ifdef BYTE_COMBINING_DEBUG
1380 /* We have copied text into the gap, but we have not marked
1381 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1382 here, for both the previous text and the following text.
1383 Meanwhile, GPT_ADDR does point to
1384 the text that has been stored by copy_text. */
1385 if (count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
)
1386 || count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
))
1390 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1392 /* Record the insertion first, so that when we undo,
1393 the deletion will be undone first. Thus, undo
1394 will insert before deleting, and thus will keep
1395 the markers before and after this text separate. */
1396 record_insert (from
+ SCHARS (deletion
), inschars
);
1397 record_delete (from
, deletion
);
1400 GAP_SIZE
-= outgoing_insbytes
;
1404 GPT_BYTE
+= outgoing_insbytes
;
1405 ZV_BYTE
+= outgoing_insbytes
;
1406 Z_BYTE
+= outgoing_insbytes
;
1407 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1412 /* Adjust the overlay center as needed. This must be done after
1413 adjusting the markers that bound the overlays. */
1414 adjust_overlays_for_delete (from
, nchars_del
);
1415 adjust_overlays_for_insert (from
, inschars
);
1417 /* Adjust markers for the deletion and the insertion. */
1419 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1420 inschars
, outgoing_insbytes
);
1422 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1424 /* Get the intervals for the part of the string we are inserting--
1425 not including the combined-before bytes. */
1426 intervals
= STRING_INTERVALS (new);
1427 /* Insert those intervals. */
1428 graft_intervals_into_buffer (intervals
, from
, inschars
,
1429 current_buffer
, inherit
);
1431 /* Relocate point as if it were a marker. */
1433 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1434 (from_byte
+ outgoing_insbytes
1435 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1437 if (outgoing_insbytes
== 0)
1438 evaporate_overlays (from
);
1443 CHARS_MODIFF
= MODIFF
;
1446 signal_after_change (from
, nchars_del
, GPT
- from
);
1447 update_compositions (from
, GPT
, CHECK_BORDER
);
1450 /* Replace the text from character positions FROM to TO with
1451 the text in INS of length INSCHARS.
1452 Keep the text properties that applied to the old characters
1453 (extending them to all the new chars if there are more new chars).
1455 Note that this does not yet handle markers quite right.
1457 If MARKERS is nonzero, relocate markers.
1459 Unlike most functions at this level, never call
1460 prepare_to_modify_buffer and never call signal_after_change. */
1463 replace_range_2 (ptrdiff_t from
, ptrdiff_t from_byte
,
1464 ptrdiff_t to
, ptrdiff_t to_byte
,
1465 const char *ins
, ptrdiff_t inschars
, ptrdiff_t insbytes
,
1468 ptrdiff_t nbytes_del
, nchars_del
;
1472 nchars_del
= to
- from
;
1473 nbytes_del
= to_byte
- from_byte
;
1475 if (nbytes_del
<= 0 && insbytes
== 0)
1478 /* Make sure the gap is somewhere in or next to what we are deleting. */
1480 gap_right (from
, from_byte
);
1482 gap_left (to
, to_byte
, 0);
1484 GAP_SIZE
+= nbytes_del
;
1487 ZV_BYTE
-= nbytes_del
;
1488 Z_BYTE
-= nbytes_del
;
1490 GPT_BYTE
= from_byte
;
1491 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1496 if (GPT
- BEG
< BEG_UNCHANGED
)
1497 BEG_UNCHANGED
= GPT
- BEG
;
1498 if (Z
- GPT
< END_UNCHANGED
)
1499 END_UNCHANGED
= Z
- GPT
;
1501 if (GAP_SIZE
< insbytes
)
1502 make_gap (insbytes
- GAP_SIZE
);
1504 /* Copy the replacement text into the buffer. */
1505 memcpy (GPT_ADDR
, ins
, insbytes
);
1507 #ifdef BYTE_COMBINING_DEBUG
1508 /* We have copied text into the gap, but we have not marked
1509 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1510 here, for both the previous text and the following text.
1511 Meanwhile, GPT_ADDR does point to
1512 the text that has been stored by copy_text. */
1513 if (count_combining_before (GPT_ADDR
, insbytes
, from
, from_byte
)
1514 || count_combining_after (GPT_ADDR
, insbytes
, from
, from_byte
))
1518 GAP_SIZE
-= insbytes
;
1522 GPT_BYTE
+= insbytes
;
1523 ZV_BYTE
+= insbytes
;
1525 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1530 /* Adjust the overlay center as needed. This must be done after
1531 adjusting the markers that bound the overlays. */
1532 if (nchars_del
!= inschars
)
1534 adjust_overlays_for_insert (from
, inschars
);
1535 adjust_overlays_for_delete (from
+ inschars
, nchars_del
);
1538 /* Adjust markers for the deletion and the insertion. */
1540 && ! (nchars_del
== 1 && inschars
== 1 && nbytes_del
== insbytes
))
1541 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1542 inschars
, insbytes
);
1544 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1546 /* Relocate point as if it were a marker. */
1547 if (from
< PT
&& (nchars_del
!= inschars
|| nbytes_del
!= insbytes
))
1550 /* PT was within the deleted text. Move it to FROM. */
1551 adjust_point (from
- PT
, from_byte
- PT_BYTE
);
1553 adjust_point (inschars
- nchars_del
, insbytes
- nbytes_del
);
1557 evaporate_overlays (from
);
1562 CHARS_MODIFF
= MODIFF
;
1565 /* Delete characters in current buffer
1566 from FROM up to (but not including) TO.
1567 If TO comes before FROM, we delete nothing. */
1570 del_range (ptrdiff_t from
, ptrdiff_t to
)
1572 del_range_1 (from
, to
, 1, 0);
1575 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1576 RET_STRING says to return the deleted text. */
1579 del_range_1 (ptrdiff_t from
, ptrdiff_t to
, int prepare
, int ret_string
)
1581 ptrdiff_t from_byte
, to_byte
;
1582 Lisp_Object deletion
;
1583 struct gcpro gcpro1
;
1585 /* Make args be valid */
1596 ptrdiff_t range_length
= to
- from
;
1597 prepare_to_modify_buffer (from
, to
, &from
);
1598 to
= min (ZV
, from
+ range_length
);
1601 from_byte
= CHAR_TO_BYTE (from
);
1602 to_byte
= CHAR_TO_BYTE (to
);
1604 deletion
= del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
);
1606 signal_after_change (from
, to
- from
, 0);
1607 update_compositions (from
, from
, CHECK_HEAD
);
1612 /* Like del_range_1 but args are byte positions, not char positions. */
1615 del_range_byte (ptrdiff_t from_byte
, ptrdiff_t to_byte
, int prepare
)
1619 /* Make args be valid */
1620 if (from_byte
< BEGV_BYTE
)
1621 from_byte
= BEGV_BYTE
;
1622 if (to_byte
> ZV_BYTE
)
1625 if (to_byte
<= from_byte
)
1628 from
= BYTE_TO_CHAR (from_byte
);
1629 to
= BYTE_TO_CHAR (to_byte
);
1633 ptrdiff_t old_from
= from
, old_to
= Z
- to
;
1634 ptrdiff_t range_length
= to
- from
;
1635 prepare_to_modify_buffer (from
, to
, &from
);
1636 to
= from
+ range_length
;
1638 if (old_from
!= from
)
1639 from_byte
= CHAR_TO_BYTE (from
);
1645 else if (old_to
== Z
- to
)
1646 to_byte
= CHAR_TO_BYTE (to
);
1649 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1650 signal_after_change (from
, to
- from
, 0);
1651 update_compositions (from
, from
, CHECK_HEAD
);
1654 /* Like del_range_1, but positions are specified both as charpos
1658 del_range_both (ptrdiff_t from
, ptrdiff_t from_byte
,
1659 ptrdiff_t to
, ptrdiff_t to_byte
, int prepare
)
1661 /* Make args be valid */
1662 if (from_byte
< BEGV_BYTE
)
1663 from_byte
= BEGV_BYTE
;
1664 if (to_byte
> ZV_BYTE
)
1667 if (to_byte
<= from_byte
)
1677 ptrdiff_t old_from
= from
, old_to
= Z
- to
;
1678 ptrdiff_t range_length
= to
- from
;
1679 prepare_to_modify_buffer (from
, to
, &from
);
1680 to
= from
+ range_length
;
1682 if (old_from
!= from
)
1683 from_byte
= CHAR_TO_BYTE (from
);
1689 else if (old_to
== Z
- to
)
1690 to_byte
= CHAR_TO_BYTE (to
);
1693 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1694 signal_after_change (from
, to
- from
, 0);
1695 update_compositions (from
, from
, CHECK_HEAD
);
1698 /* Delete a range of text, specified both as character positions
1699 and byte positions. FROM and TO are character positions,
1700 while FROM_BYTE and TO_BYTE are byte positions.
1701 If RET_STRING is true, the deleted area is returned as a string. */
1704 del_range_2 (ptrdiff_t from
, ptrdiff_t from_byte
,
1705 ptrdiff_t to
, ptrdiff_t to_byte
, int ret_string
)
1707 register ptrdiff_t nbytes_del
, nchars_del
;
1708 Lisp_Object deletion
;
1712 nchars_del
= to
- from
;
1713 nbytes_del
= to_byte
- from_byte
;
1715 /* Make sure the gap is somewhere in or next to what we are deleting. */
1717 gap_right (from
, from_byte
);
1719 gap_left (to
, to_byte
, 0);
1721 #ifdef BYTE_COMBINING_DEBUG
1722 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
1723 Z_BYTE
- to_byte
, from
, from_byte
))
1727 if (ret_string
|| ! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1728 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1732 /* Relocate all markers pointing into the new, larger gap
1733 to point at the end of the text before the gap.
1734 Do this before recording the deletion,
1735 so that undo handles this after reinserting the text. */
1736 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1738 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1739 record_delete (from
, deletion
);
1741 CHARS_MODIFF
= MODIFF
;
1743 /* Relocate point as if it were a marker. */
1745 adjust_point (from
- (PT
< to
? PT
: to
),
1746 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
1748 offset_intervals (current_buffer
, from
, - nchars_del
);
1750 /* Adjust the overlay center as needed. This must be done after
1751 adjusting the markers that bound the overlays. */
1752 adjust_overlays_for_delete (from
, nchars_del
);
1754 GAP_SIZE
+= nbytes_del
;
1755 ZV_BYTE
-= nbytes_del
;
1756 Z_BYTE
-= nbytes_del
;
1760 GPT_BYTE
= from_byte
;
1761 if (GAP_SIZE
> 0 && !current_buffer
->text
->inhibit_shrinking
)
1762 /* Put an anchor, unless called from decode_coding_object which
1763 needs to access the previous gap contents. */
1769 if (GPT
- BEG
< BEG_UNCHANGED
)
1770 BEG_UNCHANGED
= GPT
- BEG
;
1771 if (Z
- GPT
< END_UNCHANGED
)
1772 END_UNCHANGED
= Z
- GPT
;
1776 evaporate_overlays (from
);
1781 /* Call this if you're about to change the region of BUFFER from
1782 character positions START to END. This checks the read-only
1783 properties of the region, calls the necessary modification hooks,
1784 and warns the next redisplay that it should pay attention to that
1787 If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
1788 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1791 modify_region (struct buffer
*buffer
, ptrdiff_t start
, ptrdiff_t end
,
1792 int preserve_chars_modiff
)
1794 struct buffer
*old_buffer
= current_buffer
;
1796 if (buffer
!= old_buffer
)
1797 set_buffer_internal (buffer
);
1799 prepare_to_modify_buffer (start
, end
, NULL
);
1801 BUF_COMPUTE_UNCHANGED (buffer
, start
- 1, end
);
1803 if (MODIFF
<= SAVE_MODIFF
)
1804 record_first_change ();
1806 if (! preserve_chars_modiff
)
1807 CHARS_MODIFF
= MODIFF
;
1809 BVAR (buffer
, point_before_scroll
) = Qnil
;
1811 if (buffer
!= old_buffer
)
1812 set_buffer_internal (old_buffer
);
1815 /* Check that it is okay to modify the buffer between START and END,
1816 which are char positions.
1818 Run the before-change-function, if any. If intervals are in use,
1819 verify that the text to be modified is not read-only, and call
1820 any modification properties the text may have.
1822 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1823 by holding its value temporarily in a marker. */
1826 prepare_to_modify_buffer (ptrdiff_t start
, ptrdiff_t end
,
1827 ptrdiff_t *preserve_ptr
)
1829 struct buffer
*base_buffer
;
1831 if (!NILP (BVAR (current_buffer
, read_only
)))
1832 Fbarf_if_buffer_read_only ();
1834 /* Let redisplay consider other windows than selected_window
1835 if modifying another buffer. */
1836 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
1837 ++windows_or_buffers_changed
;
1839 if (BUF_INTERVALS (current_buffer
) != 0)
1843 Lisp_Object preserve_marker
;
1844 struct gcpro gcpro1
;
1845 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
1846 GCPRO1 (preserve_marker
);
1847 verify_interval_modification (current_buffer
, start
, end
);
1848 *preserve_ptr
= marker_position (preserve_marker
);
1849 unchain_marker (XMARKER (preserve_marker
));
1853 verify_interval_modification (current_buffer
, start
, end
);
1856 /* For indirect buffers, use the base buffer to check clashes. */
1857 if (current_buffer
->base_buffer
!= 0)
1858 base_buffer
= current_buffer
->base_buffer
;
1860 base_buffer
= current_buffer
;
1862 #ifdef CLASH_DETECTION
1863 if (!NILP (BVAR (base_buffer
, file_truename
))
1864 /* Make binding buffer-file-name to nil effective. */
1865 && !NILP (BVAR (base_buffer
, filename
))
1866 && SAVE_MODIFF
>= MODIFF
)
1867 lock_file (BVAR (base_buffer
, file_truename
));
1869 /* At least warn if this file has changed on disk since it was visited. */
1870 if (!NILP (BVAR (base_buffer
, filename
))
1871 && SAVE_MODIFF
>= MODIFF
1872 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
1873 && !NILP (Ffile_exists_p (BVAR (base_buffer
, filename
))))
1874 call1 (intern ("ask-user-about-supersession-threat"),
1875 BVAR (base_buffer
,filename
));
1876 #endif /* not CLASH_DETECTION */
1878 /* If `select-active-regions' is non-nil, save the region text. */
1879 if (!NILP (BVAR (current_buffer
, mark_active
))
1880 && !inhibit_modification_hooks
1881 && XMARKER (BVAR (current_buffer
, mark
))->buffer
1882 && NILP (Vsaved_region_selection
)
1883 && (EQ (Vselect_active_regions
, Qonly
)
1884 ? EQ (CAR_SAFE (Vtransient_mark_mode
), Qonly
)
1885 : (!NILP (Vselect_active_regions
)
1886 && !NILP (Vtransient_mark_mode
))))
1888 ptrdiff_t b
= XMARKER (BVAR (current_buffer
, mark
))->charpos
;
1891 Vsaved_region_selection
= make_buffer_string (b
, e
, 0);
1893 Vsaved_region_selection
= make_buffer_string (e
, b
, 0);
1896 signal_before_change (start
, end
, preserve_ptr
);
1898 if (current_buffer
->newline_cache
)
1899 invalidate_region_cache (current_buffer
,
1900 current_buffer
->newline_cache
,
1901 start
- BEG
, Z
- end
);
1902 if (current_buffer
->width_run_cache
)
1903 invalidate_region_cache (current_buffer
,
1904 current_buffer
->width_run_cache
,
1905 start
- BEG
, Z
- end
);
1907 Vdeactivate_mark
= Qt
;
1910 /* These macros work with an argument named `preserve_ptr'
1911 and a local variable named `preserve_marker'. */
1913 #define PRESERVE_VALUE \
1914 if (preserve_ptr && NILP (preserve_marker)) \
1915 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
1917 #define RESTORE_VALUE \
1918 if (! NILP (preserve_marker)) \
1920 *preserve_ptr = marker_position (preserve_marker); \
1921 unchain_marker (XMARKER (preserve_marker)); \
1924 #define PRESERVE_START_END \
1925 if (NILP (start_marker)) \
1926 start_marker = Fcopy_marker (start, Qnil); \
1927 if (NILP (end_marker)) \
1928 end_marker = Fcopy_marker (end, Qnil);
1930 #define FETCH_START \
1931 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
1934 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
1936 /* Set a variable to nil if an error occurred.
1937 Don't change the variable if there was no error.
1938 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
1939 VARIABLE is the variable to maybe set to nil.
1940 NO-ERROR-FLAG is nil if there was an error,
1941 anything else meaning no error (so this function does nothing). */
1943 reset_var_on_error (Lisp_Object val
)
1945 if (NILP (XCDR (val
)))
1946 Fset (XCAR (val
), Qnil
);
1950 /* Signal a change to the buffer immediately before it happens.
1951 START_INT and END_INT are the bounds of the text to be changed.
1953 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1954 by holding its value temporarily in a marker. */
1957 signal_before_change (ptrdiff_t start_int
, ptrdiff_t end_int
,
1958 ptrdiff_t *preserve_ptr
)
1960 Lisp_Object start
, end
;
1961 Lisp_Object start_marker
, end_marker
;
1962 Lisp_Object preserve_marker
;
1963 struct gcpro gcpro1
, gcpro2
, gcpro3
;
1964 ptrdiff_t count
= SPECPDL_INDEX ();
1966 if (inhibit_modification_hooks
)
1969 start
= make_number (start_int
);
1970 end
= make_number (end_int
);
1971 preserve_marker
= Qnil
;
1972 start_marker
= Qnil
;
1974 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
1976 specbind (Qinhibit_modification_hooks
, Qt
);
1978 /* If buffer is unmodified, run a special hook for that case. The
1979 check for Vfirst_change_hook is just a minor optimization. */
1980 if (SAVE_MODIFF
>= MODIFF
1981 && !NILP (Vfirst_change_hook
))
1985 Frun_hooks (1, &Qfirst_change_hook
);
1988 /* Now run the before-change-functions if any. */
1989 if (!NILP (Vbefore_change_functions
))
1991 Lisp_Object args
[3];
1992 Lisp_Object rvoe_arg
= Fcons (Qbefore_change_functions
, Qnil
);
1997 /* Mark before-change-functions to be reset to nil in case of error. */
1998 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2000 /* Actually run the hook functions. */
2001 args
[0] = Qbefore_change_functions
;
2002 args
[1] = FETCH_START
;
2003 args
[2] = FETCH_END
;
2004 Frun_hook_with_args (3, args
);
2006 /* There was no error: unarm the reset_on_error. */
2007 XSETCDR (rvoe_arg
, Qt
);
2010 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2013 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2014 FETCH_START
, FETCH_END
, Qnil
);
2017 if (! NILP (start_marker
))
2018 free_marker (start_marker
);
2019 if (! NILP (end_marker
))
2020 free_marker (end_marker
);
2024 unbind_to (count
, Qnil
);
2027 /* Signal a change immediately after it happens.
2028 CHARPOS is the character position of the start of the changed text.
2029 LENDEL is the number of characters of the text before the change.
2030 (Not the whole buffer; just the part that was changed.)
2031 LENINS is the number of characters in that part of the text
2032 after the change. */
2035 signal_after_change (ptrdiff_t charpos
, ptrdiff_t lendel
, ptrdiff_t lenins
)
2037 ptrdiff_t count
= SPECPDL_INDEX ();
2038 if (inhibit_modification_hooks
)
2041 /* If we are deferring calls to the after-change functions
2042 and there are no before-change functions,
2043 just record the args that we were going to use. */
2044 if (! NILP (Vcombine_after_change_calls
)
2045 && NILP (Vbefore_change_functions
)
2046 && !current_buffer
->overlays_before
2047 && !current_buffer
->overlays_after
)
2051 if (!NILP (combine_after_change_list
)
2052 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2053 Fcombine_after_change_execute ();
2055 elt
= Fcons (make_number (charpos
- BEG
),
2056 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2057 Fcons (make_number (lenins
- lendel
), Qnil
)));
2058 combine_after_change_list
2059 = Fcons (elt
, combine_after_change_list
);
2060 combine_after_change_buffer
= Fcurrent_buffer ();
2065 if (!NILP (combine_after_change_list
))
2066 Fcombine_after_change_execute ();
2068 specbind (Qinhibit_modification_hooks
, Qt
);
2070 if (!NILP (Vafter_change_functions
))
2072 Lisp_Object args
[4];
2073 Lisp_Object rvoe_arg
= Fcons (Qafter_change_functions
, Qnil
);
2075 /* Mark after-change-functions to be reset to nil in case of error. */
2076 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2078 /* Actually run the hook functions. */
2079 args
[0] = Qafter_change_functions
;
2080 XSETFASTINT (args
[1], charpos
);
2081 XSETFASTINT (args
[2], charpos
+ lenins
);
2082 XSETFASTINT (args
[3], lendel
);
2083 Frun_hook_with_args (4, args
);
2085 /* There was no error: unarm the reset_on_error. */
2086 XSETCDR (rvoe_arg
, Qt
);
2089 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2090 report_overlay_modification (make_number (charpos
),
2091 make_number (charpos
+ lenins
),
2093 make_number (charpos
),
2094 make_number (charpos
+ lenins
),
2095 make_number (lendel
));
2097 /* After an insertion, call the text properties
2098 insert-behind-hooks or insert-in-front-hooks. */
2100 report_interval_modification (make_number (charpos
),
2101 make_number (charpos
+ lenins
));
2103 unbind_to (count
, Qnil
);
2107 Fcombine_after_change_execute_1 (Lisp_Object val
)
2109 Vcombine_after_change_calls
= val
;
2113 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2114 Scombine_after_change_execute
, 0, 0, 0,
2115 doc
: /* This function is for use internally in `combine-after-change-calls'. */)
2118 ptrdiff_t count
= SPECPDL_INDEX ();
2119 ptrdiff_t beg
, end
, change
;
2120 ptrdiff_t begpos
, endpos
;
2123 if (NILP (combine_after_change_list
))
2126 /* It is rare for combine_after_change_buffer to be invalid, but
2127 possible. It can happen when combine-after-change-calls is
2128 non-nil, and insertion calls a file handler (e.g. through
2129 lock_file) which scribbles into a temp file -- cyd */
2130 if (!BUFFERP (combine_after_change_buffer
)
2131 || NILP (BVAR (XBUFFER (combine_after_change_buffer
), name
)))
2133 combine_after_change_list
= Qnil
;
2137 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2139 Fset_buffer (combine_after_change_buffer
);
2141 /* # chars unchanged at beginning of buffer. */
2143 /* # chars unchanged at end of buffer. */
2145 /* Total amount of insertion (negative for deletion). */
2148 /* Scan the various individual changes,
2149 accumulating the range info in BEG, END and CHANGE. */
2150 for (tail
= combine_after_change_list
; CONSP (tail
);
2154 ptrdiff_t thisbeg
, thisend
, thischange
;
2156 /* Extract the info from the next element. */
2160 thisbeg
= XINT (XCAR (elt
));
2165 thisend
= XINT (XCAR (elt
));
2170 thischange
= XINT (XCAR (elt
));
2172 /* Merge this range into the accumulated range. */
2173 change
+= thischange
;
2180 /* Get the current start and end positions of the range
2181 that was changed. */
2185 /* We are about to handle these, so discard them. */
2186 combine_after_change_list
= Qnil
;
2188 /* Now run the after-change functions for real.
2189 Turn off the flag that defers them. */
2190 record_unwind_protect (Fcombine_after_change_execute_1
,
2191 Vcombine_after_change_calls
);
2192 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2193 update_compositions (begpos
, endpos
, CHECK_ALL
);
2195 return unbind_to (count
, Qnil
);
2199 syms_of_insdel (void)
2201 staticpro (&combine_after_change_list
);
2202 staticpro (&combine_after_change_buffer
);
2203 combine_after_change_list
= Qnil
;
2204 combine_after_change_buffer
= Qnil
;
2206 DEFVAR_BOOL ("check-markers-debug-flag", check_markers_debug_flag
,
2207 doc
: /* Non-nil means enable debugging checks for invalid marker positions. */);
2208 check_markers_debug_flag
= 0;
2209 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls
,
2210 doc
: /* Used internally by the `combine-after-change-calls' macro. */);
2211 Vcombine_after_change_calls
= Qnil
;
2213 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks
,
2214 doc
: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2215 This affects `before-change-functions' and `after-change-functions',
2216 as well as hooks attached to text properties and overlays. */);
2217 inhibit_modification_hooks
= 0;
2218 DEFSYM (Qinhibit_modification_hooks
, "inhibit-modification-hooks");
2220 defsubr (&Scombine_after_change_execute
);