1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985-1986, 1993-1995, 1997-2011
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"
39 static void insert_from_string_1 (Lisp_Object string
,
40 EMACS_INT pos
, EMACS_INT pos_byte
,
41 EMACS_INT nchars
, EMACS_INT nbytes
,
42 int inherit
, int before_markers
);
43 static void insert_from_buffer_1 (struct buffer
*buf
,
44 EMACS_INT from
, EMACS_INT nchars
,
46 static void gap_left (EMACS_INT charpos
, EMACS_INT bytepos
, int newgap
);
47 static void gap_right (EMACS_INT charpos
, EMACS_INT bytepos
);
48 static void adjust_markers_for_insert (EMACS_INT from
, EMACS_INT from_byte
,
49 EMACS_INT to
, EMACS_INT to_byte
,
51 static void adjust_markers_for_replace (EMACS_INT
, EMACS_INT
, EMACS_INT
,
52 EMACS_INT
, EMACS_INT
, EMACS_INT
);
53 static void adjust_point (EMACS_INT nchars
, EMACS_INT nbytes
);
55 static Lisp_Object
Fcombine_after_change_execute (void);
57 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
58 describing changes which happened while combine_after_change_calls
59 was nonzero. We use this to decide how to call them
60 once the deferral ends.
63 BEG-UNCHANGED is the number of chars before the changed range.
64 END-UNCHANGED is the number of chars after the changed range,
65 and CHANGE-AMOUNT is the number of characters inserted by the change
66 (negative for a deletion). */
67 static Lisp_Object combine_after_change_list
;
69 /* Buffer which combine_after_change_list is about. */
70 static Lisp_Object combine_after_change_buffer
;
72 Lisp_Object Qinhibit_modification_hooks
;
74 static void signal_before_change (EMACS_INT
, EMACS_INT
, EMACS_INT
*);
76 #define CHECK_MARKERS() \
79 if (check_markers_debug_flag) \
87 register struct Lisp_Marker
*tail
;
88 int multibyte
= ! NILP (BVAR (current_buffer
, enable_multibyte_characters
));
90 for (tail
= BUF_MARKERS (current_buffer
); tail
; tail
= tail
->next
)
92 if (tail
->buffer
->text
!= current_buffer
->text
)
94 if (tail
->charpos
> Z
)
96 if (tail
->bytepos
> Z_BYTE
)
98 if (multibyte
&& ! CHAR_HEAD_P (FETCH_BYTE (tail
->bytepos
)))
103 /* Move gap to position CHARPOS.
104 Note that this can quit! */
107 move_gap (EMACS_INT charpos
)
109 move_gap_both (charpos
, charpos_to_bytepos (charpos
));
112 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
113 Note that this can quit! */
116 move_gap_both (EMACS_INT charpos
, EMACS_INT bytepos
)
118 if (bytepos
< GPT_BYTE
)
119 gap_left (charpos
, bytepos
, 0);
120 else if (bytepos
> GPT_BYTE
)
121 gap_right (charpos
, bytepos
);
124 /* Move the gap to a position less than the current GPT.
125 BYTEPOS describes the new position as a byte position,
126 and CHARPOS is the corresponding char position.
127 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
130 gap_left (EMACS_INT charpos
, EMACS_INT bytepos
, int newgap
)
132 register unsigned char *to
, *from
;
133 register EMACS_INT i
;
137 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
144 /* Now copy the characters. To move the gap down,
145 copy characters up. */
149 /* I gets number of characters left to copy. */
150 i
= new_s1
- bytepos
;
153 /* If a quit is requested, stop copying now.
154 Change BYTEPOS to be where we have actually moved the gap to. */
158 charpos
= BYTE_TO_CHAR (bytepos
);
161 /* Move at most 32000 chars before checking again for a quit. */
166 memmove (to
, from
, i
);
169 /* Adjust buffer data structure, to put the gap at BYTEPOS.
170 BYTEPOS is where the loop above stopped, which may be what
171 was specified or may be where a quit was detected. */
174 if (bytepos
< charpos
)
176 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
180 /* Move the gap to a position greater than the current GPT.
181 BYTEPOS describes the new position as a byte position,
182 and CHARPOS is the corresponding char position. */
185 gap_right (EMACS_INT charpos
, EMACS_INT bytepos
)
187 register unsigned char *to
, *from
;
188 register EMACS_INT i
;
191 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
198 /* Now copy the characters. To move the gap up,
199 copy characters down. */
203 /* I gets number of characters left to copy. */
204 i
= bytepos
- new_s1
;
207 /* If a quit is requested, stop copying now.
208 Change BYTEPOS to be where we have actually moved the gap to. */
212 charpos
= BYTE_TO_CHAR (bytepos
);
215 /* Move at most 32000 chars before checking again for a quit. */
219 memmove (to
, from
, i
);
225 if (bytepos
< charpos
)
227 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
231 /* Adjust all markers for a deletion
232 whose range in bytes is FROM_BYTE to TO_BYTE.
233 The range in charpos is FROM to TO.
235 This function assumes that the gap is adjacent to
236 or inside of the range being deleted. */
239 adjust_markers_for_delete (EMACS_INT from
, EMACS_INT from_byte
,
240 EMACS_INT to
, EMACS_INT to_byte
)
243 register struct Lisp_Marker
*m
;
244 register EMACS_INT charpos
;
246 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
248 charpos
= m
->charpos
;
253 /* If the marker is after the deletion,
254 relocate by number of chars / bytes deleted. */
257 m
->charpos
-= to
- from
;
258 m
->bytepos
-= to_byte
- from_byte
;
260 /* Here's the case where a marker is inside text being deleted. */
261 else if (charpos
> from
)
263 if (! m
->insertion_type
)
264 { /* Normal markers will end up at the beginning of the
265 re-inserted text after undoing a deletion, and must be
266 adjusted to move them to the correct place. */
267 XSETMISC (marker
, m
);
268 record_marker_adjustment (marker
, from
- charpos
);
270 else if (charpos
< to
)
271 { /* Before-insertion markers will automatically move forward
272 upon re-inserting the deleted text, so we have to arrange
273 for them to move backward to the correct position. */
274 XSETMISC (marker
, m
);
275 record_marker_adjustment (marker
, to
- charpos
);
278 m
->bytepos
= from_byte
;
280 /* Here's the case where a before-insertion marker is immediately
281 before the deleted region. */
282 else if (charpos
== from
&& m
->insertion_type
)
284 /* Undoing the change uses normal insertion, which will
285 incorrectly make MARKER move forward, so we arrange for it
286 to then move backward to the correct place at the beginning
287 of the deleted region. */
288 XSETMISC (marker
, m
);
289 record_marker_adjustment (marker
, to
- from
);
295 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
296 to TO / TO_BYTE. We have to relocate the charpos of every marker
297 that points after the insertion (but not their bytepos).
299 When a marker points at the insertion point,
300 we advance it if either its insertion-type is t
301 or BEFORE_MARKERS is true. */
304 adjust_markers_for_insert (EMACS_INT from
, EMACS_INT from_byte
,
305 EMACS_INT to
, EMACS_INT to_byte
, int before_markers
)
307 struct Lisp_Marker
*m
;
309 EMACS_INT nchars
= to
- from
;
310 EMACS_INT nbytes
= to_byte
- from_byte
;
312 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
314 eassert (m
->bytepos
>= m
->charpos
315 && m
->bytepos
- m
->charpos
<= Z_BYTE
- Z
);
317 if (m
->bytepos
== from_byte
)
319 if (m
->insertion_type
|| before_markers
)
321 m
->bytepos
= to_byte
;
323 if (m
->insertion_type
)
327 else if (m
->bytepos
> from_byte
)
329 m
->bytepos
+= nbytes
;
330 m
->charpos
+= nchars
;
334 /* Adjusting only markers whose insertion-type is t may result in
335 - disordered start and end in overlays, and
336 - disordered overlays in the slot `overlays_before' of current_buffer. */
339 fix_start_end_in_overlays(from
, to
);
340 fix_overlays_before (current_buffer
, from
, to
);
344 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
346 This is used only when the value of point changes due to an insert
347 or delete; it does not represent a conceptual change in point as a
348 marker. In particular, point is not crossing any interval
349 boundaries, so there's no need to use the usual SET_PT macro. In
350 fact it would be incorrect to do so, because either the old or the
351 new value of point is out of sync with the current set of
355 adjust_point (EMACS_INT nchars
, EMACS_INT nbytes
)
357 SET_BUF_PT_BOTH (current_buffer
, PT
+ nchars
, PT_BYTE
+ nbytes
);
358 /* In a single-byte buffer, the two positions must be equal. */
359 eassert (PT_BYTE
>= PT
&& PT_BYTE
- PT
<= ZV_BYTE
- ZV
);
362 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
363 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
364 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
368 adjust_markers_for_replace (EMACS_INT from
, EMACS_INT from_byte
,
369 EMACS_INT old_chars
, EMACS_INT old_bytes
,
370 EMACS_INT new_chars
, EMACS_INT new_bytes
)
372 register struct Lisp_Marker
*m
;
373 EMACS_INT prev_to_byte
= from_byte
+ old_bytes
;
374 EMACS_INT diff_chars
= new_chars
- old_chars
;
375 EMACS_INT diff_bytes
= new_bytes
- old_bytes
;
377 for (m
= BUF_MARKERS (current_buffer
); m
; m
= m
->next
)
379 if (m
->bytepos
>= prev_to_byte
)
381 m
->charpos
+= diff_chars
;
382 m
->bytepos
+= diff_bytes
;
384 else if (m
->bytepos
> from_byte
)
387 m
->bytepos
= from_byte
;
395 /* Make the gap NBYTES_ADDED bytes longer. */
398 make_gap_larger (EMACS_INT nbytes_added
)
401 EMACS_INT real_gap_loc
;
402 EMACS_INT real_gap_loc_byte
;
403 EMACS_INT old_gap_size
;
405 /* If we have to get more space, get enough to last a while. */
406 nbytes_added
+= 2000;
408 { EMACS_INT total_size
= Z_BYTE
- BEG_BYTE
+ GAP_SIZE
+ nbytes_added
;
410 /* Don't allow a buffer size that won't fit in a Lisp integer. */
411 || total_size
!= XINT (make_number (total_size
)))
412 error ("Buffer exceeds maximum size");
415 enlarge_buffer_text (current_buffer
, nbytes_added
);
417 /* Prevent quitting in move_gap. */
422 real_gap_loc_byte
= GPT_BYTE
;
423 old_gap_size
= GAP_SIZE
;
425 /* Call the newly allocated space a gap at the end of the whole space. */
427 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
428 GAP_SIZE
= nbytes_added
;
430 /* Move the new gap down to be consecutive with the end of the old one.
431 This adjusts the markers properly too. */
432 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
434 /* Now combine the two into one large gap. */
435 GAP_SIZE
+= old_gap_size
;
437 GPT_BYTE
= real_gap_loc_byte
;
445 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
447 /* Make the gap NBYTES_REMOVED bytes shorter. */
450 make_gap_smaller (EMACS_INT nbytes_removed
)
453 EMACS_INT real_gap_loc
;
454 EMACS_INT real_gap_loc_byte
;
456 EMACS_INT real_Z_byte
;
457 EMACS_INT real_beg_unchanged
;
458 EMACS_INT new_gap_size
;
460 /* Make sure the gap is at least 20 bytes. */
461 if (GAP_SIZE
- nbytes_removed
< 20)
462 nbytes_removed
= GAP_SIZE
- 20;
464 /* Prevent quitting in move_gap. */
469 real_gap_loc_byte
= GPT_BYTE
;
470 new_gap_size
= GAP_SIZE
- nbytes_removed
;
472 real_Z_byte
= Z_BYTE
;
473 real_beg_unchanged
= BEG_UNCHANGED
;
475 /* Pretend that the last unwanted part of the gap is the entire gap,
476 and that the first desired part of the gap is part of the buffer
478 memset (GPT_ADDR
, 0, new_gap_size
);
480 GPT_BYTE
+= new_gap_size
;
482 Z_BYTE
+= new_gap_size
;
483 GAP_SIZE
= nbytes_removed
;
485 /* Move the unwanted pretend gap to the end of the buffer. This
486 adjusts the markers properly too. */
487 gap_right (Z
, Z_BYTE
);
489 enlarge_buffer_text (current_buffer
, -nbytes_removed
);
491 /* Now restore the desired gap. */
492 GAP_SIZE
= new_gap_size
;
494 GPT_BYTE
= real_gap_loc_byte
;
496 Z_BYTE
= real_Z_byte
;
497 BEG_UNCHANGED
= real_beg_unchanged
;
505 #endif /* USE_MMAP_FOR_BUFFERS || REL_ALLOC || DOUG_LEA_MALLOC */
508 make_gap (EMACS_INT nbytes_added
)
510 if (nbytes_added
>= 0)
511 make_gap_larger (nbytes_added
);
512 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
514 make_gap_smaller (-nbytes_added
);
518 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
519 FROM_MULTIBYTE says whether the incoming text is multibyte.
520 TO_MULTIBYTE says whether to store the text as multibyte.
521 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
523 Return the number of bytes stored at TO_ADDR. */
526 copy_text (const unsigned char *from_addr
, unsigned char *to_addr
,
527 EMACS_INT nbytes
, int from_multibyte
, int to_multibyte
)
529 if (from_multibyte
== to_multibyte
)
531 memcpy (to_addr
, from_addr
, nbytes
);
534 else if (from_multibyte
)
536 EMACS_INT nchars
= 0;
537 EMACS_INT bytes_left
= nbytes
;
539 while (bytes_left
> 0)
542 c
= STRING_CHAR_AND_LENGTH (from_addr
, thislen
);
543 if (! ASCII_CHAR_P (c
))
546 from_addr
+= thislen
;
547 bytes_left
-= thislen
;
554 unsigned char *initial_to_addr
= to_addr
;
556 /* Convert single-byte to multibyte. */
559 int c
= *from_addr
++;
561 if (!ASCII_CHAR_P (c
))
563 c
= BYTE8_TO_CHAR (c
);
564 to_addr
+= CHAR_STRING (c
, to_addr
);
568 /* Special case for speed. */
569 *to_addr
++ = c
, nbytes
--;
571 return to_addr
- initial_to_addr
;
575 /* Insert a string of specified length before point.
576 This function judges multibyteness based on
577 enable_multibyte_characters in the current buffer;
578 it never converts between single-byte and multibyte.
580 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
581 prepare_to_modify_buffer could relocate the text. */
584 insert (const char *string
, EMACS_INT nbytes
)
588 EMACS_INT len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
589 insert_1_both (string
, len
, nbytes
, 0, 1, 0);
591 signal_after_change (opoint
, 0, len
);
592 update_compositions (opoint
, PT
, CHECK_BORDER
);
596 /* Likewise, but inherit text properties from neighboring characters. */
599 insert_and_inherit (const char *string
, EMACS_INT nbytes
)
603 EMACS_INT len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
604 insert_1_both (string
, len
, nbytes
, 1, 1, 0);
606 signal_after_change (opoint
, 0, len
);
607 update_compositions (opoint
, PT
, CHECK_BORDER
);
611 /* Insert the character C before point. Do not inherit text properties. */
616 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
619 if (! NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
620 len
= CHAR_STRING (c
, str
);
627 insert ((char *) str
, len
);
630 /* Insert the null-terminated string S before point. */
633 insert_string (const char *s
)
635 insert (s
, strlen (s
));
638 /* Like `insert' except that all markers pointing at the place where
639 the insertion happens are adjusted to point after it.
640 Don't use this function to insert part of a Lisp string,
641 since gc could happen and relocate it. */
644 insert_before_markers (const char *string
, EMACS_INT nbytes
)
648 EMACS_INT len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
649 insert_1_both (string
, len
, nbytes
, 0, 1, 1);
651 signal_after_change (opoint
, 0, len
);
652 update_compositions (opoint
, PT
, CHECK_BORDER
);
656 /* Likewise, but inherit text properties from neighboring characters. */
659 insert_before_markers_and_inherit (const char *string
,
664 EMACS_INT len
= chars_in_text ((unsigned char *) string
, nbytes
), opoint
;
665 insert_1_both (string
, len
, nbytes
, 1, 1, 1);
667 signal_after_change (opoint
, 0, len
);
668 update_compositions (opoint
, PT
, CHECK_BORDER
);
672 /* Subroutine used by the insert functions above. */
675 insert_1 (const char *string
, EMACS_INT nbytes
,
676 int inherit
, int prepare
, int before_markers
)
678 insert_1_both (string
, chars_in_text ((unsigned char *) string
, nbytes
),
679 nbytes
, inherit
, prepare
, before_markers
);
683 #ifdef BYTE_COMBINING_DEBUG
685 /* See if the bytes before POS/POS_BYTE combine with bytes
686 at the start of STRING to form a single character.
687 If so, return the number of bytes at the start of STRING
688 which combine in this way. Otherwise, return 0. */
691 count_combining_before (const unsigned char *string
, EMACS_INT length
,
692 EMACS_INT pos
, EMACS_INT pos_byte
)
694 int len
, combining_bytes
;
695 const unsigned char *p
;
697 if (NILP (current_buffer
->enable_multibyte_characters
))
700 /* At first, we can exclude the following cases:
701 (1) STRING[0] can't be a following byte of multibyte sequence.
702 (2) POS is the start of the current buffer.
703 (3) A character before POS is not a multibyte character. */
704 if (length
== 0 || CHAR_HEAD_P (*string
)) /* case (1) */
706 if (pos_byte
== BEG_BYTE
) /* case (2) */
709 p
= BYTE_POS_ADDR (pos_byte
- 1);
710 while (! CHAR_HEAD_P (*p
)) p
--, len
++;
711 if (! LEADING_CODE_P (*p
)) /* case (3) */
714 combining_bytes
= BYTES_BY_CHAR_HEAD (*p
) - len
;
715 if (combining_bytes
<= 0)
716 /* The character preceding POS is, complete and no room for
717 combining bytes (combining_bytes == 0), or an independent 8-bit
718 character (combining_bytes < 0). */
721 /* We have a combination situation. Count the bytes at STRING that
724 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
727 return (combining_bytes
< p
- string
? combining_bytes
: p
- string
);
730 /* See if the bytes after POS/POS_BYTE combine with bytes
731 at the end of STRING to form a single character.
732 If so, return the number of bytes after POS/POS_BYTE
733 which combine in this way. Otherwise, return 0. */
736 count_combining_after (const unsigned char *string
,
737 EMACS_INT length
, EMACS_INT pos
, EMACS_INT pos_byte
)
739 EMACS_INT opos_byte
= pos_byte
;
744 if (NILP (current_buffer
->enable_multibyte_characters
))
747 /* At first, we can exclude the following cases:
748 (1) The last byte of STRING is an ASCII.
749 (2) POS is the last of the current buffer.
750 (3) A character at POS can't be a following byte of multibyte
752 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1])) /* case (1) */
754 if (pos_byte
== Z_BYTE
) /* case (2) */
756 bufp
= BYTE_POS_ADDR (pos_byte
);
757 if (CHAR_HEAD_P (*bufp
)) /* case (3) */
761 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
767 /* All characters in STRING are not character head. We must
768 check also preceding bytes at POS. We are sure that the gap
770 unsigned char *p
= BEG_ADDR
;
772 while (i
>= 0 && ! CHAR_HEAD_P (p
[i
]))
774 if (i
< 0 || !LEADING_CODE_P (p
[i
]))
777 bytes
= BYTES_BY_CHAR_HEAD (p
[i
]);
778 return (bytes
<= pos_byte
- 1 - i
+ length
780 : bytes
- (pos_byte
- 1 - i
+ length
));
782 if (!LEADING_CODE_P (string
[i
]))
785 bytes
= BYTES_BY_CHAR_HEAD (string
[i
]) - (length
- i
);
787 while (!CHAR_HEAD_P (*bufp
)) bufp
++, pos_byte
++;
789 return (bytes
<= pos_byte
- opos_byte
? bytes
: pos_byte
- opos_byte
);
795 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
796 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
797 are the same as in insert_1. */
800 insert_1_both (const char *string
,
801 EMACS_INT nchars
, EMACS_INT nbytes
,
802 int inherit
, int prepare
, int before_markers
)
807 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
811 /* Do this before moving and increasing the gap,
812 because the before-change hooks might move the gap
813 or make it smaller. */
814 prepare_to_modify_buffer (PT
, PT
, NULL
);
817 move_gap_both (PT
, PT_BYTE
);
818 if (GAP_SIZE
< nbytes
)
819 make_gap (nbytes
- GAP_SIZE
);
821 #ifdef BYTE_COMBINING_DEBUG
822 if (count_combining_before (string
, nbytes
, PT
, PT_BYTE
)
823 || count_combining_after (string
, nbytes
, PT
, PT_BYTE
))
827 /* Record deletion of the surrounding text that combines with
828 the insertion. This, together with recording the insertion,
829 will add up to the right stuff in the undo list. */
830 record_insert (PT
, nchars
);
832 CHARS_MODIFF
= MODIFF
;
834 memcpy (GPT_ADDR
, string
, nbytes
);
843 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
848 /* The insert may have been in the unchanged region, so check again. */
849 if (Z
- GPT
< END_UNCHANGED
)
850 END_UNCHANGED
= Z
- GPT
;
852 adjust_overlays_for_insert (PT
, nchars
);
853 adjust_markers_for_insert (PT
, PT_BYTE
,
854 PT
+ nchars
, PT_BYTE
+ nbytes
,
857 if (BUF_INTERVALS (current_buffer
) != 0)
858 offset_intervals (current_buffer
, PT
, nchars
);
860 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
861 set_text_properties (make_number (PT
), make_number (PT
+ nchars
),
864 adjust_point (nchars
, nbytes
);
869 /* Insert the part of the text of STRING, a Lisp object assumed to be
870 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
871 starting at position POS / POS_BYTE. If the text of STRING has properties,
872 copy them into the buffer.
874 It does not work to use `insert' for this, because a GC could happen
875 before we copy the stuff into the buffer, and relocate the string
876 without insert noticing. */
879 insert_from_string (Lisp_Object string
, EMACS_INT pos
, EMACS_INT pos_byte
,
880 EMACS_INT length
, EMACS_INT length_byte
, int inherit
)
882 EMACS_INT opoint
= PT
;
884 if (SCHARS (string
) == 0)
887 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
889 signal_after_change (opoint
, 0, PT
- opoint
);
890 update_compositions (opoint
, PT
, CHECK_BORDER
);
893 /* Like `insert_from_string' except that all markers pointing
894 at the place where the insertion happens are adjusted to point after it. */
897 insert_from_string_before_markers (Lisp_Object string
,
898 EMACS_INT pos
, EMACS_INT pos_byte
,
899 EMACS_INT length
, EMACS_INT length_byte
,
902 EMACS_INT opoint
= PT
;
904 if (SCHARS (string
) == 0)
907 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
909 signal_after_change (opoint
, 0, PT
- opoint
);
910 update_compositions (opoint
, PT
, CHECK_BORDER
);
913 /* Subroutine of the insertion functions above. */
916 insert_from_string_1 (Lisp_Object string
, EMACS_INT pos
, EMACS_INT pos_byte
,
917 EMACS_INT nchars
, EMACS_INT nbytes
,
918 int inherit
, int before_markers
)
921 EMACS_INT outgoing_nbytes
= nbytes
;
924 /* Make OUTGOING_NBYTES describe the text
925 as it will be inserted in this buffer. */
927 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
928 outgoing_nbytes
= nchars
;
929 else if (! STRING_MULTIBYTE (string
))
931 = count_size_as_multibyte (SDATA (string
) + pos_byte
,
935 /* Do this before moving and increasing the gap,
936 because the before-change hooks might move the gap
937 or make it smaller. */
938 prepare_to_modify_buffer (PT
, PT
, NULL
);
941 move_gap_both (PT
, PT_BYTE
);
942 if (GAP_SIZE
< outgoing_nbytes
)
943 make_gap (outgoing_nbytes
- GAP_SIZE
);
946 /* Copy the string text into the buffer, perhaps converting
947 between single-byte and multibyte. */
948 copy_text (SDATA (string
) + pos_byte
, GPT_ADDR
, nbytes
,
949 STRING_MULTIBYTE (string
),
950 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
952 #ifdef BYTE_COMBINING_DEBUG
953 /* We have copied text into the gap, but we have not altered
954 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
955 to these functions and get the same results as we would
956 have got earlier on. Meanwhile, PT_ADDR does point to
957 the text that has been stored by copy_text. */
958 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
959 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
963 record_insert (PT
, nchars
);
965 CHARS_MODIFF
= MODIFF
;
967 GAP_SIZE
-= outgoing_nbytes
;
971 GPT_BYTE
+= outgoing_nbytes
;
972 ZV_BYTE
+= outgoing_nbytes
;
973 Z_BYTE
+= outgoing_nbytes
;
974 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
979 /* The insert may have been in the unchanged region, so check again. */
980 if (Z
- GPT
< END_UNCHANGED
)
981 END_UNCHANGED
= Z
- GPT
;
983 adjust_overlays_for_insert (PT
, nchars
);
984 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
985 PT_BYTE
+ outgoing_nbytes
,
988 offset_intervals (current_buffer
, PT
, nchars
);
990 intervals
= STRING_INTERVALS (string
);
991 /* Get the intervals for the part of the string we are inserting. */
992 if (nbytes
< SBYTES (string
))
993 intervals
= copy_intervals (intervals
, pos
, nchars
);
995 /* Insert those intervals. */
996 graft_intervals_into_buffer (intervals
, PT
, nchars
,
997 current_buffer
, inherit
);
999 adjust_point (nchars
, outgoing_nbytes
);
1004 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1005 starting at GPT_ADDR. */
1008 insert_from_gap (EMACS_INT nchars
, EMACS_INT nbytes
)
1010 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1013 record_insert (GPT
, nchars
);
1023 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1028 adjust_overlays_for_insert (GPT
- nchars
, nchars
);
1029 adjust_markers_for_insert (GPT
- nchars
, GPT_BYTE
- nbytes
,
1032 if (BUF_INTERVALS (current_buffer
) != 0)
1034 offset_intervals (current_buffer
, GPT
- nchars
, nchars
);
1035 graft_intervals_into_buffer (NULL_INTERVAL
, GPT
- nchars
, nchars
,
1039 if (GPT
- nchars
< PT
)
1040 adjust_point (nchars
, nbytes
);
1045 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1046 current buffer. If the text in BUF has properties, they are absorbed
1047 into the current buffer.
1049 It does not work to use `insert' for this, because a malloc could happen
1050 and relocate BUF's text before the copy happens. */
1053 insert_from_buffer (struct buffer
*buf
,
1054 EMACS_INT charpos
, EMACS_INT nchars
, int inherit
)
1056 EMACS_INT opoint
= PT
;
1058 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1059 signal_after_change (opoint
, 0, PT
- opoint
);
1060 update_compositions (opoint
, PT
, CHECK_BORDER
);
1064 insert_from_buffer_1 (struct buffer
*buf
,
1065 EMACS_INT from
, EMACS_INT nchars
, int inherit
)
1067 register Lisp_Object temp
;
1068 EMACS_INT chunk
, chunk_expanded
;
1069 EMACS_INT from_byte
= buf_charpos_to_bytepos (buf
, from
);
1070 EMACS_INT to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1071 EMACS_INT incoming_nbytes
= to_byte
- from_byte
;
1072 EMACS_INT outgoing_nbytes
= incoming_nbytes
;
1075 /* Make OUTGOING_NBYTES describe the text
1076 as it will be inserted in this buffer. */
1078 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1079 outgoing_nbytes
= nchars
;
1080 else if (NILP (BVAR (buf
, enable_multibyte_characters
)))
1082 EMACS_INT outgoing_before_gap
= 0;
1083 EMACS_INT outgoing_after_gap
= 0;
1085 if (from
< BUF_GPT (buf
))
1087 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1088 if (chunk
> incoming_nbytes
)
1089 chunk
= incoming_nbytes
;
1091 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1097 if (chunk
< incoming_nbytes
)
1099 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
,
1101 incoming_nbytes
- chunk
);
1103 outgoing_nbytes
= outgoing_before_gap
+ outgoing_after_gap
;
1106 /* Make sure point-max won't overflow after this insertion. */
1107 XSETINT (temp
, outgoing_nbytes
+ Z
);
1108 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1109 error ("Maximum buffer size exceeded");
1111 /* Do this before moving and increasing the gap,
1112 because the before-change hooks might move the gap
1113 or make it smaller. */
1114 prepare_to_modify_buffer (PT
, PT
, NULL
);
1117 move_gap_both (PT
, PT_BYTE
);
1118 if (GAP_SIZE
< outgoing_nbytes
)
1119 make_gap (outgoing_nbytes
- GAP_SIZE
);
1121 if (from
< BUF_GPT (buf
))
1123 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1124 if (chunk
> incoming_nbytes
)
1125 chunk
= incoming_nbytes
;
1126 /* Record number of output bytes, so we know where
1127 to put the output from the second copy_text. */
1129 = copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1131 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1132 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1135 chunk_expanded
= chunk
= 0;
1137 if (chunk
< incoming_nbytes
)
1138 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1139 GPT_ADDR
+ chunk_expanded
, incoming_nbytes
- chunk
,
1140 ! NILP (BVAR (buf
, enable_multibyte_characters
)),
1141 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1143 #ifdef BYTE_COMBINING_DEBUG
1144 /* We have copied text into the gap, but we have not altered
1145 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1146 to these functions and get the same results as we would
1147 have got earlier on. Meanwhile, GPT_ADDR does point to
1148 the text that has been stored by copy_text. */
1149 if (count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
)
1150 || count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
))
1154 record_insert (PT
, nchars
);
1156 CHARS_MODIFF
= MODIFF
;
1158 GAP_SIZE
-= outgoing_nbytes
;
1162 GPT_BYTE
+= outgoing_nbytes
;
1163 ZV_BYTE
+= outgoing_nbytes
;
1164 Z_BYTE
+= outgoing_nbytes
;
1165 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1170 /* The insert may have been in the unchanged region, so check again. */
1171 if (Z
- GPT
< END_UNCHANGED
)
1172 END_UNCHANGED
= Z
- GPT
;
1174 adjust_overlays_for_insert (PT
, nchars
);
1175 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1176 PT_BYTE
+ outgoing_nbytes
,
1179 if (BUF_INTERVALS (current_buffer
) != 0)
1180 offset_intervals (current_buffer
, PT
, nchars
);
1182 /* Get the intervals for the part of the string we are inserting. */
1183 intervals
= BUF_INTERVALS (buf
);
1184 if (nchars
< BUF_Z (buf
) - BUF_BEG (buf
))
1186 if (buf
== current_buffer
&& PT
<= from
)
1188 intervals
= copy_intervals (intervals
, from
, nchars
);
1191 /* Insert those intervals. */
1192 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1194 adjust_point (nchars
, outgoing_nbytes
);
1197 /* Record undo information and adjust markers and position keepers for
1198 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1199 chars (LEN_BYTE bytes) which resides in the gap just after
1202 PREV_TEXT nil means the new text was just inserted. */
1205 adjust_after_replace (EMACS_INT from
, EMACS_INT from_byte
,
1206 Lisp_Object prev_text
, EMACS_INT len
, EMACS_INT len_byte
)
1208 EMACS_INT nchars_del
= 0, nbytes_del
= 0;
1210 #ifdef BYTE_COMBINING_DEBUG
1211 if (count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
)
1212 || count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
))
1216 if (STRINGP (prev_text
))
1218 nchars_del
= SCHARS (prev_text
);
1219 nbytes_del
= SBYTES (prev_text
);
1222 /* Update various buffer positions for the new text. */
1223 GAP_SIZE
-= len_byte
;
1225 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1226 GPT
+= len
; GPT_BYTE
+= len_byte
;
1227 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1230 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1233 adjust_markers_for_insert (from
, from_byte
,
1234 from
+ len
, from_byte
+ len_byte
, 0);
1236 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1239 record_delete (from
, prev_text
);
1240 record_insert (from
, len
);
1243 if (len
> nchars_del
)
1244 adjust_overlays_for_insert (from
, len
- nchars_del
);
1245 else if (len
< nchars_del
)
1246 adjust_overlays_for_delete (from
, nchars_del
- len
);
1247 if (BUF_INTERVALS (current_buffer
) != 0)
1249 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1253 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1255 /* As byte combining will decrease Z, we must check this again. */
1256 if (Z
- GPT
< END_UNCHANGED
)
1257 END_UNCHANGED
= Z
- GPT
;
1262 evaporate_overlays (from
);
1264 CHARS_MODIFF
= MODIFF
;
1267 /* Record undo information, adjust markers and position keepers for an
1268 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1269 text already exists in the current buffer but character length (TO
1270 - FROM) may be incorrect, the correct length is NEWLEN. */
1273 adjust_after_insert (EMACS_INT from
, EMACS_INT from_byte
,
1274 EMACS_INT to
, EMACS_INT to_byte
, EMACS_INT newlen
)
1276 EMACS_INT len
= to
- from
, len_byte
= to_byte
- from_byte
;
1279 move_gap_both (to
, to_byte
);
1280 GAP_SIZE
+= len_byte
;
1281 GPT
-= len
; GPT_BYTE
-= len_byte
;
1282 ZV
-= len
; ZV_BYTE
-= len_byte
;
1283 Z
-= len
; Z_BYTE
-= len_byte
;
1284 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1287 /* Replace the text from character positions FROM to TO with NEW,
1288 If PREPARE is nonzero, call prepare_to_modify_buffer.
1289 If INHERIT, the newly inserted text should inherit text properties
1290 from the surrounding non-deleted text. */
1292 /* Note that this does not yet handle markers quite right.
1293 Also it needs to record a single undo-entry that does a replacement
1294 rather than a separate delete and insert.
1295 That way, undo will also handle markers properly.
1297 But if MARKERS is 0, don't relocate markers. */
1300 replace_range (EMACS_INT from
, EMACS_INT to
, Lisp_Object
new,
1301 int prepare
, int inherit
, int markers
)
1303 EMACS_INT inschars
= SCHARS (new);
1304 EMACS_INT insbytes
= SBYTES (new);
1305 EMACS_INT from_byte
, to_byte
;
1306 EMACS_INT nbytes_del
, nchars_del
;
1307 register Lisp_Object temp
;
1308 struct gcpro gcpro1
;
1310 EMACS_INT outgoing_insbytes
= insbytes
;
1311 Lisp_Object deletion
;
1320 EMACS_INT range_length
= to
- from
;
1321 prepare_to_modify_buffer (from
, to
, &from
);
1322 to
= from
+ range_length
;
1327 /* Make args be valid */
1333 from_byte
= CHAR_TO_BYTE (from
);
1334 to_byte
= CHAR_TO_BYTE (to
);
1336 nchars_del
= to
- from
;
1337 nbytes_del
= to_byte
- from_byte
;
1339 if (nbytes_del
<= 0 && insbytes
== 0)
1342 /* Make OUTGOING_INSBYTES describe the text
1343 as it will be inserted in this buffer. */
1345 if (NILP (BVAR (current_buffer
, enable_multibyte_characters
)))
1346 outgoing_insbytes
= inschars
;
1347 else if (! STRING_MULTIBYTE (new))
1349 = count_size_as_multibyte (SDATA (new), insbytes
);
1351 /* Make sure point-max won't overflow after this insertion. */
1352 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1353 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1354 error ("Maximum buffer size exceeded");
1358 /* Make sure the gap is somewhere in or next to what we are deleting. */
1360 gap_right (from
, from_byte
);
1362 gap_left (to
, to_byte
, 0);
1364 /* Even if we don't record for undo, we must keep the original text
1365 because we may have to recover it because of inappropriate byte
1367 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1368 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1370 GAP_SIZE
+= nbytes_del
;
1373 ZV_BYTE
-= nbytes_del
;
1374 Z_BYTE
-= nbytes_del
;
1376 GPT_BYTE
= from_byte
;
1377 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1382 if (GPT
- BEG
< BEG_UNCHANGED
)
1383 BEG_UNCHANGED
= GPT
- BEG
;
1384 if (Z
- GPT
< END_UNCHANGED
)
1385 END_UNCHANGED
= Z
- GPT
;
1387 if (GAP_SIZE
< insbytes
)
1388 make_gap (insbytes
- GAP_SIZE
);
1390 /* Copy the string text into the buffer, perhaps converting
1391 between single-byte and multibyte. */
1392 copy_text (SDATA (new), GPT_ADDR
, insbytes
,
1393 STRING_MULTIBYTE (new),
1394 ! NILP (BVAR (current_buffer
, enable_multibyte_characters
)));
1396 #ifdef BYTE_COMBINING_DEBUG
1397 /* We have copied text into the gap, but we have not marked
1398 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1399 here, for both the previous text and the following text.
1400 Meanwhile, GPT_ADDR does point to
1401 the text that has been stored by copy_text. */
1402 if (count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
)
1403 || count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
))
1407 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1409 /* Record the insertion first, so that when we undo,
1410 the deletion will be undone first. Thus, undo
1411 will insert before deleting, and thus will keep
1412 the markers before and after this text separate. */
1413 record_insert (from
+ SCHARS (deletion
), inschars
);
1414 record_delete (from
, deletion
);
1417 GAP_SIZE
-= outgoing_insbytes
;
1421 GPT_BYTE
+= outgoing_insbytes
;
1422 ZV_BYTE
+= outgoing_insbytes
;
1423 Z_BYTE
+= outgoing_insbytes
;
1424 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1429 /* Adjust the overlay center as needed. This must be done after
1430 adjusting the markers that bound the overlays. */
1431 adjust_overlays_for_delete (from
, nchars_del
);
1432 adjust_overlays_for_insert (from
, inschars
);
1434 /* Adjust markers for the deletion and the insertion. */
1436 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1437 inschars
, outgoing_insbytes
);
1439 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1441 /* Get the intervals for the part of the string we are inserting--
1442 not including the combined-before bytes. */
1443 intervals
= STRING_INTERVALS (new);
1444 /* Insert those intervals. */
1445 graft_intervals_into_buffer (intervals
, from
, inschars
,
1446 current_buffer
, inherit
);
1448 /* Relocate point as if it were a marker. */
1450 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1451 (from_byte
+ outgoing_insbytes
1452 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1454 if (outgoing_insbytes
== 0)
1455 evaporate_overlays (from
);
1460 CHARS_MODIFF
= MODIFF
;
1463 signal_after_change (from
, nchars_del
, GPT
- from
);
1464 update_compositions (from
, GPT
, CHECK_BORDER
);
1467 /* Replace the text from character positions FROM to TO with
1468 the text in INS of length INSCHARS.
1469 Keep the text properties that applied to the old characters
1470 (extending them to all the new chars if there are more new chars).
1472 Note that this does not yet handle markers quite right.
1474 If MARKERS is nonzero, relocate markers.
1476 Unlike most functions at this level, never call
1477 prepare_to_modify_buffer and never call signal_after_change. */
1480 replace_range_2 (EMACS_INT from
, EMACS_INT from_byte
,
1481 EMACS_INT to
, EMACS_INT to_byte
,
1482 const char *ins
, EMACS_INT inschars
, EMACS_INT insbytes
,
1485 EMACS_INT nbytes_del
, nchars_del
;
1490 nchars_del
= to
- from
;
1491 nbytes_del
= to_byte
- from_byte
;
1493 if (nbytes_del
<= 0 && insbytes
== 0)
1496 /* Make sure point-max won't overflow after this insertion. */
1497 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1498 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1499 error ("Maximum buffer size exceeded");
1501 /* Make sure the gap is somewhere in or next to what we are deleting. */
1503 gap_right (from
, from_byte
);
1505 gap_left (to
, to_byte
, 0);
1507 GAP_SIZE
+= nbytes_del
;
1510 ZV_BYTE
-= nbytes_del
;
1511 Z_BYTE
-= nbytes_del
;
1513 GPT_BYTE
= from_byte
;
1514 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1519 if (GPT
- BEG
< BEG_UNCHANGED
)
1520 BEG_UNCHANGED
= GPT
- BEG
;
1521 if (Z
- GPT
< END_UNCHANGED
)
1522 END_UNCHANGED
= Z
- GPT
;
1524 if (GAP_SIZE
< insbytes
)
1525 make_gap (insbytes
- GAP_SIZE
);
1527 /* Copy the replacement text into the buffer. */
1528 memcpy (GPT_ADDR
, ins
, insbytes
);
1530 #ifdef BYTE_COMBINING_DEBUG
1531 /* We have copied text into the gap, but we have not marked
1532 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1533 here, for both the previous text and the following text.
1534 Meanwhile, GPT_ADDR does point to
1535 the text that has been stored by copy_text. */
1536 if (count_combining_before (GPT_ADDR
, insbytes
, from
, from_byte
)
1537 || count_combining_after (GPT_ADDR
, insbytes
, from
, from_byte
))
1541 GAP_SIZE
-= insbytes
;
1545 GPT_BYTE
+= insbytes
;
1546 ZV_BYTE
+= insbytes
;
1548 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1553 /* Adjust the overlay center as needed. This must be done after
1554 adjusting the markers that bound the overlays. */
1555 if (nchars_del
!= inschars
)
1557 adjust_overlays_for_insert (from
, inschars
);
1558 adjust_overlays_for_delete (from
+ inschars
, nchars_del
);
1561 /* Adjust markers for the deletion and the insertion. */
1563 && ! (nchars_del
== 1 && inschars
== 1 && nbytes_del
== insbytes
))
1564 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1565 inschars
, insbytes
);
1567 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1569 /* Relocate point as if it were a marker. */
1570 if (from
< PT
&& (nchars_del
!= inschars
|| nbytes_del
!= insbytes
))
1573 /* PT was within the deleted text. Move it to FROM. */
1574 adjust_point (from
- PT
, from_byte
- PT_BYTE
);
1576 adjust_point (inschars
- nchars_del
, insbytes
- nbytes_del
);
1580 evaporate_overlays (from
);
1585 CHARS_MODIFF
= MODIFF
;
1588 /* Delete characters in current buffer
1589 from FROM up to (but not including) TO.
1590 If TO comes before FROM, we delete nothing. */
1593 del_range (EMACS_INT from
, EMACS_INT to
)
1595 del_range_1 (from
, to
, 1, 0);
1598 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1599 RET_STRING says to return the deleted text. */
1602 del_range_1 (EMACS_INT from
, EMACS_INT to
, int prepare
, int ret_string
)
1604 EMACS_INT from_byte
, to_byte
;
1605 Lisp_Object deletion
;
1606 struct gcpro gcpro1
;
1608 /* Make args be valid */
1619 EMACS_INT range_length
= to
- from
;
1620 prepare_to_modify_buffer (from
, to
, &from
);
1621 to
= min (ZV
, from
+ range_length
);
1624 from_byte
= CHAR_TO_BYTE (from
);
1625 to_byte
= CHAR_TO_BYTE (to
);
1627 deletion
= del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
);
1629 signal_after_change (from
, to
- from
, 0);
1630 update_compositions (from
, from
, CHECK_HEAD
);
1635 /* Like del_range_1 but args are byte positions, not char positions. */
1638 del_range_byte (EMACS_INT from_byte
, EMACS_INT to_byte
, int prepare
)
1642 /* Make args be valid */
1643 if (from_byte
< BEGV_BYTE
)
1644 from_byte
= BEGV_BYTE
;
1645 if (to_byte
> ZV_BYTE
)
1648 if (to_byte
<= from_byte
)
1651 from
= BYTE_TO_CHAR (from_byte
);
1652 to
= BYTE_TO_CHAR (to_byte
);
1656 EMACS_INT old_from
= from
, old_to
= Z
- to
;
1657 EMACS_INT range_length
= to
- from
;
1658 prepare_to_modify_buffer (from
, to
, &from
);
1659 to
= from
+ range_length
;
1661 if (old_from
!= from
)
1662 from_byte
= CHAR_TO_BYTE (from
);
1668 else if (old_to
== Z
- to
)
1669 to_byte
= CHAR_TO_BYTE (to
);
1672 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1673 signal_after_change (from
, to
- from
, 0);
1674 update_compositions (from
, from
, CHECK_HEAD
);
1677 /* Like del_range_1, but positions are specified both as charpos
1681 del_range_both (EMACS_INT from
, EMACS_INT from_byte
,
1682 EMACS_INT to
, EMACS_INT to_byte
, int prepare
)
1684 /* Make args be valid */
1685 if (from_byte
< BEGV_BYTE
)
1686 from_byte
= BEGV_BYTE
;
1687 if (to_byte
> ZV_BYTE
)
1690 if (to_byte
<= from_byte
)
1700 EMACS_INT old_from
= from
, old_to
= Z
- to
;
1701 EMACS_INT range_length
= to
- from
;
1702 prepare_to_modify_buffer (from
, to
, &from
);
1703 to
= from
+ range_length
;
1705 if (old_from
!= from
)
1706 from_byte
= CHAR_TO_BYTE (from
);
1712 else if (old_to
== Z
- to
)
1713 to_byte
= CHAR_TO_BYTE (to
);
1716 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
1717 signal_after_change (from
, to
- from
, 0);
1718 update_compositions (from
, from
, CHECK_HEAD
);
1721 /* Delete a range of text, specified both as character positions
1722 and byte positions. FROM and TO are character positions,
1723 while FROM_BYTE and TO_BYTE are byte positions.
1724 If RET_STRING is true, the deleted area is returned as a string. */
1727 del_range_2 (EMACS_INT from
, EMACS_INT from_byte
,
1728 EMACS_INT to
, EMACS_INT to_byte
, int ret_string
)
1730 register EMACS_INT nbytes_del
, nchars_del
;
1731 Lisp_Object deletion
;
1735 nchars_del
= to
- from
;
1736 nbytes_del
= to_byte
- from_byte
;
1738 /* Make sure the gap is somewhere in or next to what we are deleting. */
1740 gap_right (from
, from_byte
);
1742 gap_left (to
, to_byte
, 0);
1744 #ifdef BYTE_COMBINING_DEBUG
1745 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
1746 Z_BYTE
- to_byte
, from
, from_byte
))
1750 if (ret_string
|| ! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1751 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1755 /* Relocate all markers pointing into the new, larger gap
1756 to point at the end of the text before the gap.
1757 Do this before recording the deletion,
1758 so that undo handles this after reinserting the text. */
1759 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1761 if (! EQ (BVAR (current_buffer
, undo_list
), Qt
))
1762 record_delete (from
, deletion
);
1764 CHARS_MODIFF
= MODIFF
;
1766 /* Relocate point as if it were a marker. */
1768 adjust_point (from
- (PT
< to
? PT
: to
),
1769 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
1771 offset_intervals (current_buffer
, from
, - nchars_del
);
1773 /* Adjust the overlay center as needed. This must be done after
1774 adjusting the markers that bound the overlays. */
1775 adjust_overlays_for_delete (from
, nchars_del
);
1777 GAP_SIZE
+= nbytes_del
;
1778 ZV_BYTE
-= nbytes_del
;
1779 Z_BYTE
-= nbytes_del
;
1783 GPT_BYTE
= from_byte
;
1784 if (GAP_SIZE
> 0 && !current_buffer
->text
->inhibit_shrinking
)
1785 /* Put an anchor, unless called from decode_coding_object which
1786 needs to access the previous gap contents. */
1792 if (GPT
- BEG
< BEG_UNCHANGED
)
1793 BEG_UNCHANGED
= GPT
- BEG
;
1794 if (Z
- GPT
< END_UNCHANGED
)
1795 END_UNCHANGED
= Z
- GPT
;
1799 evaporate_overlays (from
);
1804 /* Call this if you're about to change the region of BUFFER from
1805 character positions START to END. This checks the read-only
1806 properties of the region, calls the necessary modification hooks,
1807 and warns the next redisplay that it should pay attention to that
1810 If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
1811 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1814 modify_region (struct buffer
*buffer
, EMACS_INT start
, EMACS_INT end
,
1815 int preserve_chars_modiff
)
1817 // printf("modify region\n");
1818 xwidget_modify_region();
1819 struct buffer
*old_buffer
= current_buffer
;
1821 if (buffer
!= old_buffer
)
1822 set_buffer_internal (buffer
);
1824 prepare_to_modify_buffer (start
, end
, NULL
);
1826 BUF_COMPUTE_UNCHANGED (buffer
, start
- 1, end
);
1828 if (MODIFF
<= SAVE_MODIFF
)
1829 record_first_change ();
1831 if (! preserve_chars_modiff
)
1832 CHARS_MODIFF
= MODIFF
;
1834 BVAR (buffer
, point_before_scroll
) = Qnil
;
1836 if (buffer
!= old_buffer
)
1837 set_buffer_internal (old_buffer
);
1840 /* Check that it is okay to modify the buffer between START and END,
1841 which are char positions.
1843 Run the before-change-function, if any. If intervals are in use,
1844 verify that the text to be modified is not read-only, and call
1845 any modification properties the text may have.
1847 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1848 by holding its value temporarily in a marker. */
1851 prepare_to_modify_buffer (EMACS_INT start
, EMACS_INT end
,
1852 EMACS_INT
*preserve_ptr
)
1854 struct buffer
*base_buffer
;
1856 if (!NILP (BVAR (current_buffer
, read_only
)))
1857 Fbarf_if_buffer_read_only ();
1859 /* Let redisplay consider other windows than selected_window
1860 if modifying another buffer. */
1861 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
1862 ++windows_or_buffers_changed
;
1864 if (BUF_INTERVALS (current_buffer
) != 0)
1868 Lisp_Object preserve_marker
;
1869 struct gcpro gcpro1
;
1870 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
1871 GCPRO1 (preserve_marker
);
1872 verify_interval_modification (current_buffer
, start
, end
);
1873 *preserve_ptr
= marker_position (preserve_marker
);
1874 unchain_marker (XMARKER (preserve_marker
));
1878 verify_interval_modification (current_buffer
, start
, end
);
1881 /* For indirect buffers, use the base buffer to check clashes. */
1882 if (current_buffer
->base_buffer
!= 0)
1883 base_buffer
= current_buffer
->base_buffer
;
1885 base_buffer
= current_buffer
;
1887 #ifdef CLASH_DETECTION
1888 if (!NILP (BVAR (base_buffer
, file_truename
))
1889 /* Make binding buffer-file-name to nil effective. */
1890 && !NILP (BVAR (base_buffer
, filename
))
1891 && SAVE_MODIFF
>= MODIFF
)
1892 lock_file (BVAR (base_buffer
, file_truename
));
1894 /* At least warn if this file has changed on disk since it was visited. */
1895 if (!NILP (BVAR (base_buffer
, filename
))
1896 && SAVE_MODIFF
>= MODIFF
1897 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
1898 && !NILP (Ffile_exists_p (BVAR (base_buffer
, filename
))))
1899 call1 (intern ("ask-user-about-supersession-threat"),
1900 BVAR (base_buffer
,filename
));
1901 #endif /* not CLASH_DETECTION */
1903 /* If `select-active-regions' is non-nil, save the region text. */
1904 if (!NILP (BVAR (current_buffer
, mark_active
))
1905 && !inhibit_modification_hooks
1906 && XMARKER (BVAR (current_buffer
, mark
))->buffer
1907 && NILP (Vsaved_region_selection
)
1908 && (EQ (Vselect_active_regions
, Qonly
)
1909 ? EQ (CAR_SAFE (Vtransient_mark_mode
), Qonly
)
1910 : (!NILP (Vselect_active_regions
)
1911 && !NILP (Vtransient_mark_mode
))))
1913 EMACS_INT b
= XMARKER (BVAR (current_buffer
, mark
))->charpos
;
1916 Vsaved_region_selection
= make_buffer_string (b
, e
, 0);
1918 Vsaved_region_selection
= make_buffer_string (e
, b
, 0);
1921 signal_before_change (start
, end
, preserve_ptr
);
1923 if (current_buffer
->newline_cache
)
1924 invalidate_region_cache (current_buffer
,
1925 current_buffer
->newline_cache
,
1926 start
- BEG
, Z
- end
);
1927 if (current_buffer
->width_run_cache
)
1928 invalidate_region_cache (current_buffer
,
1929 current_buffer
->width_run_cache
,
1930 start
- BEG
, Z
- end
);
1932 Vdeactivate_mark
= Qt
;
1935 /* These macros work with an argument named `preserve_ptr'
1936 and a local variable named `preserve_marker'. */
1938 #define PRESERVE_VALUE \
1939 if (preserve_ptr && NILP (preserve_marker)) \
1940 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
1942 #define RESTORE_VALUE \
1943 if (! NILP (preserve_marker)) \
1945 *preserve_ptr = marker_position (preserve_marker); \
1946 unchain_marker (XMARKER (preserve_marker)); \
1949 #define PRESERVE_START_END \
1950 if (NILP (start_marker)) \
1951 start_marker = Fcopy_marker (start, Qnil); \
1952 if (NILP (end_marker)) \
1953 end_marker = Fcopy_marker (end, Qnil);
1955 #define FETCH_START \
1956 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
1959 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
1961 /* Set a variable to nil if an error occurred.
1962 Don't change the variable if there was no error.
1963 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
1964 VARIABLE is the variable to maybe set to nil.
1965 NO-ERROR-FLAG is nil if there was an error,
1966 anything else meaning no error (so this function does nothing). */
1968 reset_var_on_error (Lisp_Object val
)
1970 if (NILP (XCDR (val
)))
1971 Fset (XCAR (val
), Qnil
);
1975 /* Signal a change to the buffer immediately before it happens.
1976 START_INT and END_INT are the bounds of the text to be changed.
1978 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1979 by holding its value temporarily in a marker. */
1982 signal_before_change (EMACS_INT start_int
, EMACS_INT end_int
,
1983 EMACS_INT
*preserve_ptr
)
1985 Lisp_Object start
, end
;
1986 Lisp_Object start_marker
, end_marker
;
1987 Lisp_Object preserve_marker
;
1988 struct gcpro gcpro1
, gcpro2
, gcpro3
;
1989 int count
= SPECPDL_INDEX ();
1991 if (inhibit_modification_hooks
)
1994 start
= make_number (start_int
);
1995 end
= make_number (end_int
);
1996 preserve_marker
= Qnil
;
1997 start_marker
= Qnil
;
1999 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
2001 specbind (Qinhibit_modification_hooks
, Qt
);
2003 /* If buffer is unmodified, run a special hook for that case. The
2004 check for Vfirst_change_hook is just a minor optimization. */
2005 if (SAVE_MODIFF
>= MODIFF
2006 && !NILP (Vfirst_change_hook
))
2010 Frun_hooks (1, &Qfirst_change_hook
);
2013 /* Now run the before-change-functions if any. */
2014 if (!NILP (Vbefore_change_functions
))
2016 Lisp_Object args
[3];
2017 Lisp_Object rvoe_arg
= Fcons (Qbefore_change_functions
, Qnil
);
2022 /* Mark before-change-functions to be reset to nil in case of error. */
2023 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2025 /* Actually run the hook functions. */
2026 args
[0] = Qbefore_change_functions
;
2027 args
[1] = FETCH_START
;
2028 args
[2] = FETCH_END
;
2029 Frun_hook_with_args (3, args
);
2031 /* There was no error: unarm the reset_on_error. */
2032 XSETCDR (rvoe_arg
, Qt
);
2035 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2038 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2039 FETCH_START
, FETCH_END
, Qnil
);
2042 if (! NILP (start_marker
))
2043 free_marker (start_marker
);
2044 if (! NILP (end_marker
))
2045 free_marker (end_marker
);
2049 unbind_to (count
, Qnil
);
2052 /* Signal a change immediately after it happens.
2053 CHARPOS is the character position of the start of the changed text.
2054 LENDEL is the number of characters of the text before the change.
2055 (Not the whole buffer; just the part that was changed.)
2056 LENINS is the number of characters in that part of the text
2057 after the change. */
2060 signal_after_change (EMACS_INT charpos
, EMACS_INT lendel
, EMACS_INT lenins
)
2062 int count
= SPECPDL_INDEX ();
2063 if (inhibit_modification_hooks
)
2066 /* If we are deferring calls to the after-change functions
2067 and there are no before-change functions,
2068 just record the args that we were going to use. */
2069 if (! NILP (Vcombine_after_change_calls
)
2070 && NILP (Vbefore_change_functions
)
2071 && !current_buffer
->overlays_before
2072 && !current_buffer
->overlays_after
)
2076 if (!NILP (combine_after_change_list
)
2077 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2078 Fcombine_after_change_execute ();
2080 elt
= Fcons (make_number (charpos
- BEG
),
2081 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2082 Fcons (make_number (lenins
- lendel
), Qnil
)));
2083 combine_after_change_list
2084 = Fcons (elt
, combine_after_change_list
);
2085 combine_after_change_buffer
= Fcurrent_buffer ();
2090 if (!NILP (combine_after_change_list
))
2091 Fcombine_after_change_execute ();
2093 specbind (Qinhibit_modification_hooks
, Qt
);
2095 if (!NILP (Vafter_change_functions
))
2097 Lisp_Object args
[4];
2098 Lisp_Object rvoe_arg
= Fcons (Qafter_change_functions
, Qnil
);
2100 /* Mark after-change-functions to be reset to nil in case of error. */
2101 record_unwind_protect (reset_var_on_error
, rvoe_arg
);
2103 /* Actually run the hook functions. */
2104 args
[0] = Qafter_change_functions
;
2105 XSETFASTINT (args
[1], charpos
);
2106 XSETFASTINT (args
[2], charpos
+ lenins
);
2107 XSETFASTINT (args
[3], lendel
);
2108 Frun_hook_with_args (4, args
);
2110 /* There was no error: unarm the reset_on_error. */
2111 XSETCDR (rvoe_arg
, Qt
);
2114 if (current_buffer
->overlays_before
|| current_buffer
->overlays_after
)
2115 report_overlay_modification (make_number (charpos
),
2116 make_number (charpos
+ lenins
),
2118 make_number (charpos
),
2119 make_number (charpos
+ lenins
),
2120 make_number (lendel
));
2122 /* After an insertion, call the text properties
2123 insert-behind-hooks or insert-in-front-hooks. */
2125 report_interval_modification (make_number (charpos
),
2126 make_number (charpos
+ lenins
));
2128 unbind_to (count
, Qnil
);
2132 Fcombine_after_change_execute_1 (Lisp_Object val
)
2134 Vcombine_after_change_calls
= val
;
2138 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2139 Scombine_after_change_execute
, 0, 0, 0,
2140 doc
: /* This function is for use internally in `combine-after-change-calls'. */)
2143 int count
= SPECPDL_INDEX ();
2144 EMACS_INT beg
, end
, change
;
2145 EMACS_INT begpos
, endpos
;
2148 if (NILP (combine_after_change_list
))
2151 /* It is rare for combine_after_change_buffer to be invalid, but
2152 possible. It can happen when combine-after-change-calls is
2153 non-nil, and insertion calls a file handler (e.g. through
2154 lock_file) which scribbles into a temp file -- cyd */
2155 if (!BUFFERP (combine_after_change_buffer
)
2156 || NILP (BVAR (XBUFFER (combine_after_change_buffer
), name
)))
2158 combine_after_change_list
= Qnil
;
2162 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2164 Fset_buffer (combine_after_change_buffer
);
2166 /* # chars unchanged at beginning of buffer. */
2168 /* # chars unchanged at end of buffer. */
2170 /* Total amount of insertion (negative for deletion). */
2173 /* Scan the various individual changes,
2174 accumulating the range info in BEG, END and CHANGE. */
2175 for (tail
= combine_after_change_list
; CONSP (tail
);
2179 EMACS_INT thisbeg
, thisend
, thischange
;
2181 /* Extract the info from the next element. */
2185 thisbeg
= XINT (XCAR (elt
));
2190 thisend
= XINT (XCAR (elt
));
2195 thischange
= XINT (XCAR (elt
));
2197 /* Merge this range into the accumulated range. */
2198 change
+= thischange
;
2205 /* Get the current start and end positions of the range
2206 that was changed. */
2210 /* We are about to handle these, so discard them. */
2211 combine_after_change_list
= Qnil
;
2213 /* Now run the after-change functions for real.
2214 Turn off the flag that defers them. */
2215 record_unwind_protect (Fcombine_after_change_execute_1
,
2216 Vcombine_after_change_calls
);
2217 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2218 update_compositions (begpos
, endpos
, CHECK_ALL
);
2220 return unbind_to (count
, Qnil
);
2224 syms_of_insdel (void)
2226 staticpro (&combine_after_change_list
);
2227 staticpro (&combine_after_change_buffer
);
2228 combine_after_change_list
= Qnil
;
2229 combine_after_change_buffer
= Qnil
;
2231 DEFVAR_BOOL ("check-markers-debug-flag", check_markers_debug_flag
,
2232 doc
: /* Non-nil means enable debugging checks for invalid marker positions. */);
2233 check_markers_debug_flag
= 0;
2234 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls
,
2235 doc
: /* Used internally by the `combine-after-change-calls' macro. */);
2236 Vcombine_after_change_calls
= Qnil
;
2238 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks
,
2239 doc
: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2240 This affects `before-change-functions' and `after-change-functions',
2241 as well as hooks attached to text properties and overlays. */);
2242 inhibit_modification_hooks
= 0;
2243 Qinhibit_modification_hooks
= intern_c_string ("inhibit-modification-hooks");
2244 staticpro (&Qinhibit_modification_hooks
);
2246 defsubr (&Scombine_after_change_execute
);