1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 86,93,94,95,97,98, 1999 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
24 #include "intervals.h"
28 #include "blockinput.h"
29 #include "region-cache.h"
35 #define min(x, y) ((x) < (y) ? (x) : (y))
36 #define max(x, y) ((x) > (y) ? (x) : (y))
38 static void insert_from_string_1
P_ ((Lisp_Object
, int, int, int, int, int, int));
39 static void insert_from_buffer_1 ();
40 static void gap_left
P_ ((int, int, int));
41 static void gap_right
P_ ((int, int));
42 static void adjust_markers_gap_motion
P_ ((int, int, int));
43 static void adjust_markers_for_insert
P_ ((int, int, int, int, int, int, int));
44 void adjust_markers_for_delete
P_ ((int, int, int, int));
45 static void adjust_markers_for_record_delete
P_ ((int, int, int, int));
46 static void adjust_point
P_ ((int, int));
48 Lisp_Object
Fcombine_after_change_execute ();
50 /* Non-nil means don't call the after-change-functions right away,
51 just record an element in Vcombine_after_change_calls_list. */
52 Lisp_Object Vcombine_after_change_calls
;
54 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
55 describing changes which happened while combine_after_change_calls
56 was nonzero. We use this to decide how to call them
57 once the deferral ends.
60 BEG-UNCHANGED is the number of chars before the changed range.
61 END-UNCHANGED is the number of chars after the changed range,
62 and CHANGE-AMOUNT is the number of characters inserted by the change
63 (negative for a deletion). */
64 Lisp_Object combine_after_change_list
;
66 /* Buffer which combine_after_change_list is about. */
67 Lisp_Object combine_after_change_buffer
;
69 /* Check all markers in the current buffer, looking for something invalid. */
71 static int check_markers_debug_flag
;
73 #define CHECK_MARKERS() \
74 if (check_markers_debug_flag) \
81 register Lisp_Object tail
;
82 int multibyte
= ! NILP (current_buffer
->enable_multibyte_characters
);
84 tail
= BUF_MARKERS (current_buffer
);
86 while (XSYMBOL (tail
) != XSYMBOL (Qnil
))
88 if (XMARKER (tail
)->buffer
->text
!= current_buffer
->text
)
90 if (XMARKER (tail
)->charpos
> Z
)
92 if (XMARKER (tail
)->bytepos
> Z_BYTE
)
94 if (multibyte
&& ! CHAR_HEAD_P (FETCH_BYTE (XMARKER (tail
)->bytepos
)))
97 tail
= XMARKER (tail
)->chain
;
101 /* Move gap to position CHARPOS.
102 Note that this can quit! */
108 move_gap_both (charpos
, charpos_to_bytepos (charpos
));
111 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
112 Note that this can quit! */
115 move_gap_both (charpos
, bytepos
)
116 int charpos
, 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 (charpos
, bytepos
, newgap
)
131 register int charpos
, bytepos
;
134 register unsigned char *to
, *from
;
139 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
146 /* Now copy the characters. To move the gap down,
147 copy characters up. */
151 /* I gets number of characters left to copy. */
152 i
= new_s1
- bytepos
;
155 /* If a quit is requested, stop copying now.
156 Change BYTEPOS to be where we have actually moved the gap to. */
160 charpos
= BYTE_TO_CHAR (bytepos
);
163 /* Move at most 32000 chars before checking again for a quit. */
168 /* bcopy is safe if the two areas of memory do not overlap
169 or on systems where bcopy is always safe for moving upward. */
170 && (BCOPY_UPWARD_SAFE
171 || to
- from
>= 128))
173 /* If overlap is not safe, avoid it by not moving too many
174 characters at once. */
175 if (!BCOPY_UPWARD_SAFE
&& i
> to
- from
)
190 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
191 BYTEPOS is where the loop above stopped, which may be what was specified
192 or may be where a quit was detected. */
193 adjust_markers_gap_motion (bytepos
, GPT_BYTE
, GAP_SIZE
);
196 if (bytepos
< charpos
)
198 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
202 /* Move the gap to a position greater than than the current GPT.
203 BYTEPOS describes the new position as a byte position,
204 and CHARPOS is the corresponding char position. */
207 gap_right (charpos
, bytepos
)
208 register int charpos
, bytepos
;
210 register unsigned char *to
, *from
;
214 BUF_COMPUTE_UNCHANGED (current_buffer
, charpos
, GPT
);
221 /* Now copy the characters. To move the gap up,
222 copy characters down. */
226 /* I gets number of characters left to copy. */
227 i
= bytepos
- new_s1
;
230 /* If a quit is requested, stop copying now.
231 Change BYTEPOS to be where we have actually moved the gap to. */
235 charpos
= BYTE_TO_CHAR (bytepos
);
238 /* Move at most 32000 chars before checking again for a quit. */
243 /* bcopy is safe if the two areas of memory do not overlap
244 or on systems where bcopy is always safe for moving downward. */
245 && (BCOPY_DOWNWARD_SAFE
246 || from
- to
>= 128))
248 /* If overlap is not safe, avoid it by not moving too many
249 characters at once. */
250 if (!BCOPY_DOWNWARD_SAFE
&& i
> from
- to
)
265 adjust_markers_gap_motion (GPT_BYTE
+ GAP_SIZE
, bytepos
+ GAP_SIZE
,
269 if (bytepos
< charpos
)
271 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
275 /* Add AMOUNT to the byte position of every marker in the current buffer
276 whose current byte position is between FROM (exclusive) and TO (inclusive).
278 Also, any markers past the outside of that interval, in the direction
279 of adjustment, are first moved back to the near end of the interval
280 and then adjusted by AMOUNT.
282 When the latter adjustment is done, if AMOUNT is negative,
283 we record the adjustment for undo. (This case happens only for
286 The markers' character positions are not altered,
287 because gap motion does not affect character positions. */
289 int adjust_markers_test
;
292 adjust_markers_gap_motion (from
, to
, amount
)
293 register int from
, to
, amount
;
295 /* Now that a marker has a bytepos, not counting the gap,
296 nothing needs to be done here. */
299 register struct Lisp_Marker
*m
;
302 marker
= BUF_MARKERS (current_buffer
);
304 while (!NILP (marker
))
306 m
= XMARKER (marker
);
310 if (mpos
> to
&& mpos
< to
+ amount
)
312 if (adjust_markers_test
)
319 /* Here's the case where a marker is inside text being deleted.
320 AMOUNT can be negative for gap motion, too,
321 but then this range contains no markers. */
322 if (mpos
> from
+ amount
&& mpos
<= from
)
324 if (adjust_markers_test
)
326 mpos
= from
+ amount
;
329 if (mpos
> from
&& mpos
<= to
)
337 /* Adjust all markers for a deletion
338 whose range in bytes is FROM_BYTE to TO_BYTE.
339 The range in charpos is FROM to TO.
341 This function assumes that the gap is adjacent to
342 or inside of the range being deleted. */
345 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
)
346 register int from
, from_byte
, to
, to_byte
;
349 register struct Lisp_Marker
*m
;
350 register int charpos
;
352 marker
= BUF_MARKERS (current_buffer
);
354 while (!NILP (marker
))
356 m
= XMARKER (marker
);
357 charpos
= m
->charpos
;
362 /* If the marker is after the deletion,
363 relocate by number of chars / bytes deleted. */
366 m
->charpos
-= to
- from
;
367 m
->bytepos
-= to_byte
- from_byte
;
370 /* Here's the case where a marker is inside text being deleted. */
371 else if (charpos
> from
)
373 record_marker_adjustment (marker
, from
- charpos
);
375 m
->bytepos
= from_byte
;
383 /* Adjust all markers for calling record_delete for combining bytes.
384 whose range in bytes is FROM_BYTE to TO_BYTE.
385 The range in charpos is FROM to TO. */
388 adjust_markers_for_record_delete (from
, from_byte
, to
, to_byte
)
389 register int from
, from_byte
, to
, to_byte
;
392 register struct Lisp_Marker
*m
;
393 register int charpos
;
395 marker
= BUF_MARKERS (current_buffer
);
397 while (!NILP (marker
))
399 m
= XMARKER (marker
);
400 charpos
= m
->charpos
;
402 /* If the marker is after the deletion,
403 relocate by number of chars / bytes deleted. */
406 /* Here's the case where a marker is inside text being deleted. */
407 else if (charpos
> from
)
408 record_marker_adjustment (marker
, from
- charpos
);
414 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
415 to TO / TO_BYTE. We have to relocate the charpos of every marker
416 that points after the insertion (but not their bytepos).
418 COMBINED_BEFORE_BYTES is the number of bytes at the start of the insertion
419 that combine into one character with the text before the insertion.
420 COMBINED_AFTER_BYTES is the number of bytes after the insertion
421 that combine into one character with the last inserted bytes.
423 When a marker points at the insertion point,
424 we advance it if either its insertion-type is t
425 or BEFORE_MARKERS is true. */
428 adjust_markers_for_insert (from
, from_byte
, to
, to_byte
,
429 combined_before_bytes
, combined_after_bytes
,
431 register int from
, from_byte
, to
, to_byte
;
432 int combined_before_bytes
, combined_after_bytes
, before_markers
;
436 int nchars
= to
- from
;
437 int nbytes
= to_byte
- from_byte
;
439 marker
= BUF_MARKERS (current_buffer
);
441 while (!NILP (marker
))
443 register struct Lisp_Marker
*m
= XMARKER (marker
);
445 /* In a single-byte buffer, a marker's two positions must be equal.
446 (If this insertion is going to combine characters, Z will
447 become different from Z_BYTE, but they might be the same now.
448 If so, the two OLD positions of the marker should be equal.) */
451 if (m
->charpos
!= m
->bytepos
)
455 if (m
->bytepos
== from_byte
)
457 if (m
->insertion_type
|| before_markers
)
459 m
->bytepos
= to_byte
+ combined_after_bytes
;
460 m
->charpos
= to
- combined_before_bytes
;
461 /* Point the marker before the combined character,
462 so that undoing the insertion puts it back where it was. */
463 if (combined_after_bytes
)
464 DEC_BOTH (m
->charpos
, m
->bytepos
);
465 if (m
->insertion_type
)
468 else if (combined_before_bytes
)
470 /* This marker doesn't "need relocation",
471 but don't leave it pointing in the middle of a character.
472 Point the marker after the combined character,
473 so that undoing the insertion puts it back where it was. */
474 m
->bytepos
+= combined_before_bytes
;
475 if (combined_before_bytes
== nbytes
)
476 /* All new bytes plus combined_after_bytes (if any)
478 m
->bytepos
+= combined_after_bytes
;
481 /* If a marker was pointing into the combining bytes
482 after the insertion, don't leave it there
483 in the middle of a character. */
484 else if (combined_after_bytes
&& m
->bytepos
>= from_byte
485 && m
->bytepos
< from_byte
+ combined_after_bytes
)
487 /* Put it after the combining bytes. */
488 m
->bytepos
= to_byte
+ combined_after_bytes
;
489 m
->charpos
= to
- combined_before_bytes
;
490 /* Now move it back before the combined character,
491 so that undoing the insertion will put it where it was. */
492 DEC_BOTH (m
->charpos
, m
->bytepos
);
494 else if (m
->bytepos
> from_byte
)
496 m
->bytepos
+= nbytes
;
497 m
->charpos
+= nchars
- combined_after_bytes
- combined_before_bytes
;
503 /* Adjusting only markers whose insertion-type is t may result in
504 disordered overlays in the slot `overlays_before'. */
506 fix_overlays_before (current_buffer
, from
, to
);
509 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
511 This is used only when the value of point changes due to an insert
512 or delete; it does not represent a conceptual change in point as a
513 marker. In particular, point is not crossing any interval
514 boundaries, so there's no need to use the usual SET_PT macro. In
515 fact it would be incorrect to do so, because either the old or the
516 new value of point is out of sync with the current set of
520 adjust_point (nchars
, nbytes
)
523 BUF_PT (current_buffer
) += nchars
;
524 BUF_PT_BYTE (current_buffer
) += nbytes
;
526 /* In a single-byte buffer, the two positions must be equal. */
532 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
533 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
536 See the comment of adjust_markers_for_insert for the args
537 COMBINED_BEFORE_BYTES and COMBINED_AFTER_BYTES. */
540 adjust_markers_for_replace (from
, from_byte
, old_chars
, old_bytes
,
541 new_chars
, new_bytes
,
542 combined_before_bytes
, combined_after_bytes
)
543 int from
, from_byte
, old_chars
, old_bytes
, new_chars
, new_bytes
;
544 int combined_before_bytes
, combined_after_bytes
;
546 Lisp_Object marker
= BUF_MARKERS (current_buffer
);
547 int prev_to_byte
= from_byte
+ old_bytes
;
549 = (new_chars
- combined_before_bytes
) - (old_chars
+ combined_after_bytes
);
550 int diff_bytes
= new_bytes
- old_bytes
;
552 while (!NILP (marker
))
554 register struct Lisp_Marker
*m
= XMARKER (marker
);
556 if (m
->bytepos
>= prev_to_byte
558 /* If this is an insertion (replacing 0 chars),
559 reject the case of a marker that is at the
560 insertion point and should stay before the insertion. */
561 || m
->bytepos
> from_byte
|| m
->insertion_type
))
563 if (m
->bytepos
< prev_to_byte
+ combined_after_bytes
)
565 /* Put it after the combining bytes. */
566 m
->bytepos
= from_byte
+ new_bytes
+ combined_after_bytes
;
567 m
->charpos
= from
+ new_chars
- combined_before_bytes
;
571 m
->charpos
= min (from
+ new_chars
, m
->charpos
+ diff_chars
);
572 m
->bytepos
= min (from_byte
+ new_bytes
,
573 m
->bytepos
+ diff_bytes
);
576 else if (m
->bytepos
>= from_byte
)
579 m
->bytepos
= from_byte
+ combined_before_bytes
;
580 /* If all new bytes are combined in addition to that there
581 are after combining bytes, we must set byte position of
582 the marker after the after combining bytes. */
583 if (combined_before_bytes
== new_bytes
)
584 m
->bytepos
+= combined_after_bytes
;
594 /* Make the gap NBYTES_ADDED bytes longer. */
597 make_gap (nbytes_added
)
600 unsigned char *result
;
603 int real_gap_loc_byte
;
606 /* If we have to get more space, get enough to last a while. */
607 nbytes_added
+= 2000;
609 /* Don't allow a buffer size that won't fit in an int
610 even if it will fit in a Lisp integer.
611 That won't work because so many places use `int'. */
613 if (Z_BYTE
- BEG_BYTE
+ GAP_SIZE
+ nbytes_added
614 >= ((unsigned) 1 << (min (BITS_PER_INT
, VALBITS
) - 1)))
615 error ("Buffer exceeds maximum size");
618 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */
619 result
= BUFFER_REALLOC (BEG_ADDR
, (Z_BYTE
- BEG_BYTE
620 + GAP_SIZE
+ nbytes_added
+ 1));
628 /* We can't unblock until the new address is properly stored. */
632 /* Prevent quitting in move_gap. */
637 real_gap_loc_byte
= GPT_BYTE
;
638 old_gap_size
= GAP_SIZE
;
640 /* Call the newly allocated space a gap at the end of the whole space. */
642 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
643 GAP_SIZE
= nbytes_added
;
645 /* Move the new gap down to be consecutive with the end of the old one.
646 This adjusts the markers properly too. */
647 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
649 /* Now combine the two into one large gap. */
650 GAP_SIZE
+= old_gap_size
;
652 GPT_BYTE
= real_gap_loc_byte
;
660 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
661 FROM_MULTIBYTE says whether the incoming text is multibyte.
662 TO_MULTIBYTE says whether to store the text as multibyte.
663 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
665 Return the number of bytes stored at TO_ADDR. */
668 copy_text (from_addr
, to_addr
, nbytes
,
669 from_multibyte
, to_multibyte
)
670 unsigned char *from_addr
;
671 unsigned char *to_addr
;
673 int from_multibyte
, to_multibyte
;
675 if (from_multibyte
== to_multibyte
)
677 bcopy (from_addr
, to_addr
, nbytes
);
680 else if (from_multibyte
)
683 int bytes_left
= nbytes
;
684 Lisp_Object tbl
= Qnil
;
686 /* We set the variable tbl to the reverse table of
687 Vnonascii_translation_table in advance. */
688 if (CHAR_TABLE_P (Vnonascii_translation_table
))
690 tbl
= Fchar_table_extra_slot (Vnonascii_translation_table
,
692 if (!CHAR_TABLE_P (tbl
))
696 /* Convert multibyte to single byte. */
697 while (bytes_left
> 0)
699 int thislen
, c
, c_save
;
700 c
= c_save
= STRING_CHAR_AND_LENGTH (from_addr
, bytes_left
, thislen
);
701 if (!SINGLE_BYTE_CHAR_P (c
))
702 c
= multibyte_char_to_unibyte (c
, tbl
);
704 from_addr
+= thislen
;
705 bytes_left
-= thislen
;
712 unsigned char *initial_to_addr
= to_addr
;
714 /* Convert single-byte to multibyte. */
717 int c
= *from_addr
++;
721 || (c
>= 0200 && !NILP (Vnonascii_translation_table
))))
723 c
= unibyte_char_to_multibyte (c
);
724 to_addr
+= CHAR_STRING (c
, to_addr
);
728 /* Special case for speed. */
729 *to_addr
++ = c
, nbytes
--;
731 return to_addr
- initial_to_addr
;
735 /* Return the number of bytes it would take
736 to convert some single-byte text to multibyte.
737 The single-byte text consists of NBYTES bytes at PTR. */
740 count_size_as_multibyte (ptr
, nbytes
)
745 int outgoing_nbytes
= 0;
747 for (i
= 0; i
< nbytes
; i
++)
749 unsigned int c
= *ptr
++;
751 if (c
< 0200 || (c
< 0240 && NILP (Vnonascii_translation_table
)))
755 c
= unibyte_char_to_multibyte (c
);
756 outgoing_nbytes
+= CHAR_BYTES (c
);
760 return outgoing_nbytes
;
763 /* Insert a string of specified length before point.
764 This function judges multibyteness based on
765 enable_multibyte_characters in the current buffer;
766 it never converts between single-byte and multibyte.
768 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
769 prepare_to_modify_buffer could relocate the text. */
772 insert (string
, nbytes
)
773 register unsigned char *string
;
779 insert_1 (string
, nbytes
, 0, 1, 0);
780 signal_after_change (opoint
, 0, PT
- opoint
);
781 update_compositions (opoint
, PT
, CHECK_BORDER
);
785 /* Likewise, but inherit text properties from neighboring characters. */
788 insert_and_inherit (string
, nbytes
)
789 register unsigned char *string
;
795 insert_1 (string
, nbytes
, 1, 1, 0);
796 signal_after_change (opoint
, 0, PT
- opoint
);
797 update_compositions (opoint
, PT
, CHECK_BORDER
);
801 /* Insert the character C before point. Do not inherit text properties. */
807 unsigned char str
[MAX_MULTIBYTE_LENGTH
];
810 if (! NILP (current_buffer
->enable_multibyte_characters
))
811 len
= CHAR_STRING (c
, str
);
821 /* Insert the null-terminated string S before point. */
827 insert (s
, strlen (s
));
830 /* Like `insert' except that all markers pointing at the place where
831 the insertion happens are adjusted to point after it.
832 Don't use this function to insert part of a Lisp string,
833 since gc could happen and relocate it. */
836 insert_before_markers (string
, nbytes
)
837 unsigned char *string
;
844 insert_1 (string
, nbytes
, 0, 1, 1);
845 signal_after_change (opoint
, 0, PT
- opoint
);
846 update_compositions (opoint
, PT
, CHECK_BORDER
);
850 /* Likewise, but inherit text properties from neighboring characters. */
853 insert_before_markers_and_inherit (string
, nbytes
)
854 unsigned char *string
;
861 insert_1 (string
, nbytes
, 1, 1, 1);
862 signal_after_change (opoint
, 0, PT
- opoint
);
863 update_compositions (opoint
, PT
, CHECK_BORDER
);
867 /* Subroutine used by the insert functions above. */
870 insert_1 (string
, nbytes
, inherit
, prepare
, before_markers
)
871 register unsigned char *string
;
873 int inherit
, prepare
, before_markers
;
875 insert_1_both (string
, chars_in_text (string
, nbytes
), nbytes
,
876 inherit
, prepare
, before_markers
);
879 /* See if the bytes before POS/POS_BYTE combine with bytes
880 at the start of STRING to form a single character.
881 If so, return the number of bytes at the start of STRING
882 which combine in this way. Otherwise, return 0. */
885 count_combining_before (string
, length
, pos
, pos_byte
)
886 unsigned char *string
;
890 int len
, combining_bytes
;
893 if (NILP (current_buffer
->enable_multibyte_characters
))
896 /* At first, we can exclude the following cases:
897 (1) STRING[0] can't be a following byte of multibyte sequence.
898 (2) POS is the start of the current buffer.
899 (3) A character before POS is not a multibyte character. */
900 if (length
== 0 || CHAR_HEAD_P (*string
)) /* case (1) */
902 if (pos_byte
== BEG_BYTE
) /* case (2) */
905 p
= BYTE_POS_ADDR (pos_byte
- 1);
906 while (! CHAR_HEAD_P (*p
)) p
--, len
++;
907 if (! BASE_LEADING_CODE_P (*p
)) /* case (3) */
910 combining_bytes
= BYTES_BY_CHAR_HEAD (*p
) - len
;
911 if (combining_bytes
<= 0)
912 /* The character preceding POS is, complete and no room for
913 combining bytes (combining_bytes == 0), or an independent 8-bit
914 character (combining_bytes < 0). */
917 /* We have a combination situation. Count the bytes at STRING that
920 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
923 return (combining_bytes
< p
- string
? combining_bytes
: p
- string
);
926 /* See if the bytes after POS/POS_BYTE combine with bytes
927 at the end of STRING to form a single character.
928 If so, return the number of bytes after POS/POS_BYTE
929 which combine in this way. Otherwise, return 0. */
932 count_combining_after (string
, length
, pos
, pos_byte
)
933 unsigned char *string
;
937 int opos_byte
= pos_byte
;
942 if (NILP (current_buffer
->enable_multibyte_characters
))
945 /* At first, we can exclude the following cases:
946 (1) The last byte of STRING is an ASCII.
947 (2) POS is the last of the current buffer.
948 (3) A character at POS can't be a following byte of multibyte
950 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1])) /* case (1) */
952 if (pos_byte
== Z_BYTE
) /* case (2) */
954 bufp
= BYTE_POS_ADDR (pos_byte
);
955 if (CHAR_HEAD_P (*bufp
)) /* case (3) */
959 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
965 /* All characters in STRING are not character head. We must
966 check also preceding bytes at POS. We are sure that the gap
968 unsigned char *p
= BEG_ADDR
;
970 while (i
>= 0 && ! CHAR_HEAD_P (p
[i
]))
972 if (i
< 0 || !BASE_LEADING_CODE_P (p
[i
]))
975 bytes
= BYTES_BY_CHAR_HEAD (p
[i
]);
976 return (bytes
<= pos_byte
- 1 - i
+ length
978 : bytes
- (pos_byte
- 1 - i
+ length
));
980 if (!BASE_LEADING_CODE_P (string
[i
]))
983 bytes
= BYTES_BY_CHAR_HEAD (string
[i
]) - (length
- i
);
985 while (!CHAR_HEAD_P (*bufp
)) bufp
++, pos_byte
++;
987 return (bytes
<= pos_byte
- opos_byte
? bytes
: pos_byte
- opos_byte
);
990 /* Adjust the position TARGET/TARGET_BYTE for the combining of NBYTES
991 following the position POS/POS_BYTE to the character preceding POS.
992 If TARGET is after POS+NBYTES, we only have to adjust the character
993 position TARGET, else, if TARGET is after POS, we have to adjust
994 both the character position TARGET and the byte position
995 TARGET_BYTE, else we don't have to do any adjustment. */
997 #define ADJUST_CHAR_POS(target, target_byte) \
999 if (target > pos + nbytes) \
1001 else if (target >= pos) \
1004 target_byte = pos_byte + nbytes; \
1008 /* Combine NBYTES stray trailing-codes, which were formerly separate
1009 characters, with the preceding character. These bytes
1010 are located after position POS / POS_BYTE, and the preceding character
1011 is located just before that position.
1013 This function does not adjust markers for byte combining. That
1014 should be done in advance by the functions
1015 adjust_markers_for_insert or adjust_markers_for_replace. */
1018 combine_bytes (pos
, pos_byte
, nbytes
)
1019 int pos
, pos_byte
, nbytes
;
1021 adjust_overlays_for_delete (pos
, nbytes
);
1023 ADJUST_CHAR_POS (BUF_PT (current_buffer
), BUF_PT_BYTE (current_buffer
));
1024 ADJUST_CHAR_POS (GPT
, GPT_BYTE
);
1025 ADJUST_CHAR_POS (Z
, Z_BYTE
);
1026 ADJUST_CHAR_POS (ZV
, ZV_BYTE
);
1028 if (BUF_INTERVALS (current_buffer
) != 0)
1029 offset_intervals (current_buffer
, pos
, - nbytes
);
1033 byte_combining_error ()
1035 error ("Byte combining across boundary of accessible buffer text inhibitted");
1038 /* If we are going to combine bytes at POS which is at a narrowed
1039 region boundary, signal an error. */
1040 #define CHECK_BYTE_COMBINING_FOR_INSERT(pos) \
1042 if ((combined_before_bytes && pos == BEGV) \
1043 || (combined_after_bytes && pos == ZV)) \
1044 byte_combining_error (); \
1048 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1049 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
1050 are the same as in insert_1. */
1053 insert_1_both (string
, nchars
, nbytes
, inherit
, prepare
, before_markers
)
1054 register unsigned char *string
;
1055 register int nchars
, nbytes
;
1056 int inherit
, prepare
, before_markers
;
1058 int combined_before_bytes
, combined_after_bytes
;
1060 if (NILP (current_buffer
->enable_multibyte_characters
))
1064 /* Do this before moving and increasing the gap,
1065 because the before-change hooks might move the gap
1066 or make it smaller. */
1067 prepare_to_modify_buffer (PT
, PT
, NULL
);
1070 move_gap_both (PT
, PT_BYTE
);
1071 if (GAP_SIZE
< nbytes
)
1072 make_gap (nbytes
- GAP_SIZE
);
1074 combined_before_bytes
1075 = count_combining_before (string
, nbytes
, PT
, PT_BYTE
);
1076 combined_after_bytes
1077 = count_combining_after (string
, nbytes
, PT
, PT_BYTE
);
1078 CHECK_BYTE_COMBINING_FOR_INSERT (PT
);
1080 /* Record deletion of the surrounding text that combines with
1081 the insertion. This, together with recording the insertion,
1082 will add up to the right stuff in the undo list.
1084 But there is no need to actually delete the combining bytes
1085 from the buffer and reinsert them. */
1087 if (combined_after_bytes
)
1089 Lisp_Object deletion
;
1092 if (! EQ (current_buffer
->undo_list
, Qt
))
1093 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1094 PT
+ combined_after_bytes
,
1095 PT_BYTE
+ combined_after_bytes
, 1);
1097 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1098 PT
+ combined_after_bytes
,
1099 PT_BYTE
+ combined_after_bytes
);
1100 if (! EQ (current_buffer
->undo_list
, Qt
))
1101 record_delete (PT
, deletion
);
1104 if (combined_before_bytes
)
1106 Lisp_Object deletion
;
1109 if (! EQ (current_buffer
->undo_list
, Qt
))
1110 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1112 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1114 if (! EQ (current_buffer
->undo_list
, Qt
))
1115 record_delete (PT
- 1, deletion
);
1118 record_insert (PT
- !!combined_before_bytes
,
1119 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1122 bcopy (string
, GPT_ADDR
, nbytes
);
1125 /* When we have combining at the end of the insertion,
1126 this is the character position before the combined character. */
1133 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1135 if (combined_after_bytes
)
1136 move_gap_both (GPT
+ combined_after_bytes
,
1137 GPT_BYTE
+ combined_after_bytes
);
1142 adjust_overlays_for_insert (PT
, nchars
);
1143 adjust_markers_for_insert (PT
, PT_BYTE
,
1144 PT
+ nchars
, PT_BYTE
+ nbytes
,
1145 combined_before_bytes
, combined_after_bytes
,
1148 if (BUF_INTERVALS (current_buffer
) != 0)
1149 offset_intervals (current_buffer
, PT
, nchars
);
1151 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
1152 set_text_properties (make_number (PT
), make_number (PT
+ nchars
),
1156 int pos
= PT
, pos_byte
= PT_BYTE
;
1158 adjust_point (nchars
+ combined_after_bytes
,
1159 nbytes
+ combined_after_bytes
);
1161 if (combined_after_bytes
)
1162 combine_bytes (pos
+ nchars
, pos_byte
+ nbytes
, combined_after_bytes
);
1164 if (combined_before_bytes
)
1165 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1171 /* Insert the part of the text of STRING, a Lisp object assumed to be
1172 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1173 starting at position POS / POS_BYTE. If the text of STRING has properties,
1174 copy them into the buffer.
1176 It does not work to use `insert' for this, because a GC could happen
1177 before we bcopy the stuff into the buffer, and relocate the string
1178 without insert noticing. */
1181 insert_from_string (string
, pos
, pos_byte
, length
, length_byte
, inherit
)
1183 register int pos
, pos_byte
, length
, length_byte
;
1187 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1189 signal_after_change (opoint
, 0, PT
- opoint
);
1190 update_compositions (opoint
, PT
, CHECK_BORDER
);
1193 /* Like `insert_from_string' except that all markers pointing
1194 at the place where the insertion happens are adjusted to point after it. */
1197 insert_from_string_before_markers (string
, pos
, pos_byte
,
1198 length
, length_byte
, inherit
)
1200 register int pos
, pos_byte
, length
, length_byte
;
1204 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1206 signal_after_change (opoint
, 0, PT
- opoint
);
1207 update_compositions (opoint
, PT
, CHECK_BORDER
);
1210 /* Subroutine of the insertion functions above. */
1213 insert_from_string_1 (string
, pos
, pos_byte
, nchars
, nbytes
,
1214 inherit
, before_markers
)
1216 register int pos
, pos_byte
, nchars
, nbytes
;
1217 int inherit
, before_markers
;
1219 struct gcpro gcpro1
;
1220 int outgoing_nbytes
= nbytes
;
1221 int combined_before_bytes
, combined_after_bytes
;
1224 /* Make OUTGOING_NBYTES describe the text
1225 as it will be inserted in this buffer. */
1227 if (NILP (current_buffer
->enable_multibyte_characters
))
1228 outgoing_nbytes
= nchars
;
1229 else if (! STRING_MULTIBYTE (string
))
1231 = count_size_as_multibyte (&XSTRING (string
)->data
[pos_byte
],
1235 /* Do this before moving and increasing the gap,
1236 because the before-change hooks might move the gap
1237 or make it smaller. */
1238 prepare_to_modify_buffer (PT
, PT
, NULL
);
1241 move_gap_both (PT
, PT_BYTE
);
1242 if (GAP_SIZE
< outgoing_nbytes
)
1243 make_gap (outgoing_nbytes
- GAP_SIZE
);
1246 /* Copy the string text into the buffer, perhaps converting
1247 between single-byte and multibyte. */
1248 copy_text (XSTRING (string
)->data
+ pos_byte
, GPT_ADDR
, nbytes
,
1249 STRING_MULTIBYTE (string
),
1250 ! NILP (current_buffer
->enable_multibyte_characters
));
1252 /* We have copied text into the gap, but we have not altered
1253 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1254 to these functions and get the same results as we would
1255 have got earlier on. Meanwhile, PT_ADDR does point to
1256 the text that has been stored by copy_text. */
1258 combined_before_bytes
1259 = count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1260 combined_after_bytes
1261 = count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1263 unsigned char save
= *(GPT_ADDR
);
1265 CHECK_BYTE_COMBINING_FOR_INSERT (PT
);
1269 /* Record deletion of the surrounding text that combines with
1270 the insertion. This, together with recording the insertion,
1271 will add up to the right stuff in the undo list.
1273 But there is no need to actually delete the combining bytes
1274 from the buffer and reinsert them. */
1276 if (combined_after_bytes
)
1278 Lisp_Object deletion
;
1281 if (! EQ (current_buffer
->undo_list
, Qt
))
1282 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1283 PT
+ combined_after_bytes
,
1284 PT_BYTE
+ combined_after_bytes
, 1);
1286 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1287 PT
+ combined_after_bytes
,
1288 PT_BYTE
+ combined_after_bytes
);
1289 if (! EQ (current_buffer
->undo_list
, Qt
))
1290 record_delete (PT
, deletion
);
1293 if (combined_before_bytes
)
1295 Lisp_Object deletion
;
1298 if (! EQ (current_buffer
->undo_list
, Qt
))
1299 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1301 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1303 if (! EQ (current_buffer
->undo_list
, Qt
))
1304 record_delete (PT
- 1, deletion
);
1307 record_insert (PT
- !!combined_before_bytes
,
1308 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1311 GAP_SIZE
-= outgoing_nbytes
;
1315 GPT_BYTE
+= outgoing_nbytes
;
1316 ZV_BYTE
+= outgoing_nbytes
;
1317 Z_BYTE
+= outgoing_nbytes
;
1318 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1320 if (combined_after_bytes
)
1321 move_gap_both (GPT
+ combined_after_bytes
,
1322 GPT_BYTE
+ combined_after_bytes
);
1327 adjust_overlays_for_insert (PT
, nchars
);
1328 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1329 PT_BYTE
+ outgoing_nbytes
,
1330 combined_before_bytes
, combined_after_bytes
,
1333 offset_intervals (current_buffer
, PT
, nchars
);
1335 intervals
= XSTRING (string
)->intervals
;
1336 /* Get the intervals for the part of the string we are inserting--
1337 not including the combined-before bytes. */
1338 if (nbytes
< STRING_BYTES (XSTRING (string
)))
1339 intervals
= copy_intervals (intervals
, pos
, nchars
);
1341 /* Insert those intervals. */
1342 graft_intervals_into_buffer (intervals
, PT
, nchars
,
1343 current_buffer
, inherit
);
1346 int pos
= PT
, pos_byte
= PT_BYTE
;
1348 adjust_point (nchars
+ combined_after_bytes
,
1349 outgoing_nbytes
+ combined_after_bytes
);
1351 if (combined_after_bytes
)
1352 combine_bytes (pos
+ nchars
, pos_byte
+ outgoing_nbytes
,
1353 combined_after_bytes
);
1355 if (combined_before_bytes
)
1356 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1360 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1361 current buffer. If the text in BUF has properties, they are absorbed
1362 into the current buffer.
1364 It does not work to use `insert' for this, because a malloc could happen
1365 and relocate BUF's text before the bcopy happens. */
1368 insert_from_buffer (buf
, charpos
, nchars
, inherit
)
1370 int charpos
, nchars
;
1375 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1376 signal_after_change (opoint
, 0, PT
- opoint
);
1377 update_compositions (opoint
, PT
, CHECK_BORDER
);
1381 insert_from_buffer_1 (buf
, from
, nchars
, inherit
)
1386 register Lisp_Object temp
;
1387 int chunk
, chunk_expanded
;
1388 int from_byte
= buf_charpos_to_bytepos (buf
, from
);
1389 int to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1390 int incoming_nbytes
= to_byte
- from_byte
;
1391 int outgoing_nbytes
= incoming_nbytes
;
1392 int combined_before_bytes
, combined_after_bytes
;
1395 /* Make OUTGOING_NBYTES describe the text
1396 as it will be inserted in this buffer. */
1398 if (NILP (current_buffer
->enable_multibyte_characters
))
1399 outgoing_nbytes
= nchars
;
1400 else if (NILP (buf
->enable_multibyte_characters
))
1402 int outgoing_before_gap
= 0;
1403 int outgoing_after_gap
= 0;
1405 if (from
< BUF_GPT (buf
))
1407 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1408 if (chunk
> incoming_nbytes
)
1409 chunk
= incoming_nbytes
;
1411 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1417 if (chunk
< incoming_nbytes
)
1419 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
,
1421 incoming_nbytes
- chunk
);
1423 outgoing_nbytes
= outgoing_before_gap
+ outgoing_after_gap
;
1426 /* Make sure point-max won't overflow after this insertion. */
1427 XSETINT (temp
, outgoing_nbytes
+ Z
);
1428 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1429 error ("Maximum buffer size exceeded");
1431 /* Do this before moving and increasing the gap,
1432 because the before-change hooks might move the gap
1433 or make it smaller. */
1434 prepare_to_modify_buffer (PT
, PT
, NULL
);
1437 move_gap_both (PT
, PT_BYTE
);
1438 if (GAP_SIZE
< outgoing_nbytes
)
1439 make_gap (outgoing_nbytes
- GAP_SIZE
);
1441 if (from
< BUF_GPT (buf
))
1443 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1444 if (chunk
> incoming_nbytes
)
1445 chunk
= incoming_nbytes
;
1446 /* Record number of output bytes, so we know where
1447 to put the output from the second copy_text. */
1449 = copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1451 ! NILP (buf
->enable_multibyte_characters
),
1452 ! NILP (current_buffer
->enable_multibyte_characters
));
1455 chunk_expanded
= chunk
= 0;
1457 if (chunk
< incoming_nbytes
)
1458 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1459 GPT_ADDR
+ chunk_expanded
, incoming_nbytes
- chunk
,
1460 ! NILP (buf
->enable_multibyte_characters
),
1461 ! NILP (current_buffer
->enable_multibyte_characters
));
1463 /* We have copied text into the gap, but we have not altered
1464 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1465 to these functions and get the same results as we would
1466 have got earlier on. Meanwhile, GPT_ADDR does point to
1467 the text that has been stored by copy_text. */
1468 combined_before_bytes
1469 = count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1470 combined_after_bytes
1471 = count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1473 unsigned char save
= *(GPT_ADDR
);
1475 CHECK_BYTE_COMBINING_FOR_INSERT (PT
);
1479 /* Record deletion of the surrounding text that combines with
1480 the insertion. This, together with recording the insertion,
1481 will add up to the right stuff in the undo list.
1483 But there is no need to actually delete the combining bytes
1484 from the buffer and reinsert them. */
1486 if (combined_after_bytes
)
1488 Lisp_Object deletion
;
1491 if (! EQ (current_buffer
->undo_list
, Qt
))
1492 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1493 PT
+ combined_after_bytes
,
1494 PT_BYTE
+ combined_after_bytes
, 1);
1496 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1497 PT
+ combined_after_bytes
,
1498 PT_BYTE
+ combined_after_bytes
);
1499 if (! EQ (current_buffer
->undo_list
, Qt
))
1500 record_delete (PT
, deletion
);
1503 if (combined_before_bytes
)
1505 Lisp_Object deletion
;
1508 if (! EQ (current_buffer
->undo_list
, Qt
))
1509 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1511 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1513 if (! EQ (current_buffer
->undo_list
, Qt
))
1514 record_delete (PT
- 1, deletion
);
1517 record_insert (PT
- !!combined_before_bytes
,
1518 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1521 GAP_SIZE
-= outgoing_nbytes
;
1525 GPT_BYTE
+= outgoing_nbytes
;
1526 ZV_BYTE
+= outgoing_nbytes
;
1527 Z_BYTE
+= outgoing_nbytes
;
1528 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1530 if (combined_after_bytes
)
1531 move_gap_both (GPT
+ combined_after_bytes
,
1532 GPT_BYTE
+ combined_after_bytes
);
1537 adjust_overlays_for_insert (PT
, nchars
);
1538 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1539 PT_BYTE
+ outgoing_nbytes
,
1540 combined_before_bytes
, combined_after_bytes
, 0);
1542 if (BUF_INTERVALS (current_buffer
) != 0)
1543 offset_intervals (current_buffer
, PT
, nchars
);
1545 /* Get the intervals for the part of the string we are inserting--
1546 not including the combined-before bytes. */
1547 intervals
= BUF_INTERVALS (buf
);
1548 if (outgoing_nbytes
< BUF_Z_BYTE (buf
) - BUF_BEG_BYTE (buf
))
1549 intervals
= copy_intervals (intervals
, from
, nchars
);
1551 /* Insert those intervals. */
1552 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1555 int pos
= PT
, pos_byte
= PT_BYTE
;
1557 adjust_point (nchars
+ combined_after_bytes
,
1558 outgoing_nbytes
+ combined_after_bytes
);
1560 if (combined_after_bytes
)
1561 combine_bytes (pos
+ nchars
, pos_byte
+ outgoing_nbytes
,
1562 combined_after_bytes
);
1564 if (combined_before_bytes
)
1565 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1569 /* This function should be called after moving gap to FROM and before
1570 altering text between FROM and TO. This adjusts various position
1571 keepers and markers as if the text is deleted. Don't forget to
1572 call adjust_after_replace after you actually alter the text. */
1575 adjust_before_replace (from
, from_byte
, to
, to_byte
)
1576 int from
, from_byte
, to
, to_byte
;
1578 Lisp_Object deletion
;
1580 if (! EQ (current_buffer
->undo_list
, Qt
))
1581 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1585 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1587 if (! EQ (current_buffer
->undo_list
, Qt
))
1588 record_delete (from
, deletion
);
1590 adjust_overlays_for_delete (from
, to
- from
);
1593 /* Record undo information and adjust markers and position keepers for
1594 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1595 chars (LEN_BYTE bytes) which resides in the gap just after
1598 PREV_TEXT nil means the new text was just inserted. */
1601 adjust_after_replace (from
, from_byte
, prev_text
, len
, len_byte
)
1602 int from
, from_byte
, len
, len_byte
;
1603 Lisp_Object prev_text
;
1605 int combined_before_bytes
1606 = count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
);
1607 int combined_after_bytes
1608 = count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
);
1609 /* This flag tells if we combine some bytes with a character before
1610 FROM. This happens even if combined_before_bytes is zero. */
1611 int combine_before
= (combined_before_bytes
1612 || (len
== 0 && combined_after_bytes
));
1614 int nchars_del
= 0, nbytes_del
= 0;
1616 if (STRINGP (prev_text
))
1618 nchars_del
= XSTRING (prev_text
)->size
;
1619 nbytes_del
= STRING_BYTES (XSTRING (prev_text
));
1622 if ((combine_before
&& from
== BEGV
)
1623 || (combined_after_bytes
&& from
== ZV
))
1625 /* We can't combine bytes nor signal an error here. So, let's
1626 pretend that the new text is just a single space. */
1628 combined_before_bytes
= combined_after_bytes
= 0;
1632 if (combined_after_bytes
)
1634 Lisp_Object deletion
;
1637 if (! EQ (current_buffer
->undo_list
, Qt
))
1638 deletion
= make_buffer_string_both (from
, from_byte
,
1639 from
+ combined_after_bytes
,
1640 from_byte
+ combined_after_bytes
,
1643 adjust_markers_for_record_delete (from
, from_byte
,
1644 from
+ combined_after_bytes
,
1645 from_byte
+ combined_after_bytes
);
1647 if (! EQ (current_buffer
->undo_list
, Qt
))
1648 record_delete (from
+ nchars_del
, deletion
);
1651 if (combined_before_bytes
1652 || (len_byte
== 0 && combined_after_bytes
> 0))
1654 Lisp_Object deletion
;
1657 if (! EQ (current_buffer
->undo_list
, Qt
))
1658 deletion
= make_buffer_string_both (from
- 1, CHAR_TO_BYTE (from
- 1),
1659 from
, from_byte
, 1);
1660 adjust_markers_for_record_delete (from
- 1, CHAR_TO_BYTE (from
- 1),
1662 if (! EQ (current_buffer
->undo_list
, Qt
))
1663 record_delete (from
- 1, deletion
);
1666 /* Update various buffer positions for the new text. */
1667 GAP_SIZE
-= len_byte
;
1669 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1670 GPT
+= len
; GPT_BYTE
+= len_byte
;
1671 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1673 /* The gap should be at character boundary. */
1674 if (combined_after_bytes
)
1675 move_gap_both (GPT
+ combined_after_bytes
,
1676 GPT_BYTE
+ combined_after_bytes
);
1678 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1680 combined_before_bytes
, combined_after_bytes
);
1681 if (! EQ (current_buffer
->undo_list
, Qt
))
1684 record_delete (from
- combine_before
, prev_text
);
1686 record_insert (from
- 1, len
- combined_before_bytes
+ 1);
1688 record_insert (from
, len
);
1691 if (len
> nchars_del
)
1692 adjust_overlays_for_insert (from
, len
- nchars_del
);
1693 else if (len
< nchars_del
)
1694 adjust_overlays_for_delete (from
, nchars_del
- len
);
1695 if (BUF_INTERVALS (current_buffer
) != 0)
1697 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1702 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1704 if (combined_after_bytes
)
1706 if (combined_before_bytes
== len_byte
)
1707 /* This is the case that all new bytes are combined. */
1708 combined_before_bytes
+= combined_after_bytes
;
1710 combine_bytes (from
+ len
, from_byte
+ len_byte
,
1711 combined_after_bytes
);
1713 if (combined_before_bytes
)
1714 combine_bytes (from
, from_byte
, combined_before_bytes
);
1717 /* As byte combining will decrease Z, we must check this again. */
1718 if (Z
- GPT
< END_UNCHANGED
)
1719 END_UNCHANGED
= Z
- GPT
;
1724 evaporate_overlays (from
);
1728 /* Record undo information, adjust markers and position keepers for an
1729 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1730 text already exists in the current buffer but character length (TO
1731 - FROM) may be incorrect, the correct length is NEWLEN. */
1734 adjust_after_insert (from
, from_byte
, to
, to_byte
, newlen
)
1735 int from
, from_byte
, to
, to_byte
, newlen
;
1737 int len
= to
- from
, len_byte
= to_byte
- from_byte
;
1740 move_gap_both (to
, to_byte
);
1741 GAP_SIZE
+= len_byte
;
1742 GPT
-= len
; GPT_BYTE
-= len_byte
;
1743 ZV
-= len
; ZV_BYTE
-= len_byte
;
1744 Z
-= len
; Z_BYTE
-= len_byte
;
1745 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1748 /* Replace the text from character positions FROM to TO with NEW,
1749 If PREPARE is nonzero, call prepare_to_modify_buffer.
1750 If INHERIT, the newly inserted text should inherit text properties
1751 from the surrounding non-deleted text. */
1753 /* Note that this does not yet handle markers quite right.
1754 Also it needs to record a single undo-entry that does a replacement
1755 rather than a separate delete and insert.
1756 That way, undo will also handle markers properly.
1758 But if MARKERS is 0, don't relocate markers. */
1761 replace_range (from
, to
, new, prepare
, inherit
, markers
)
1763 int from
, to
, prepare
, inherit
, markers
;
1765 int inschars
= XSTRING (new)->size
;
1766 int insbytes
= STRING_BYTES (XSTRING (new));
1767 int from_byte
, to_byte
;
1768 int nbytes_del
, nchars_del
;
1769 register Lisp_Object temp
;
1770 struct gcpro gcpro1
;
1771 int combined_before_bytes
, combined_after_bytes
;
1773 int outgoing_insbytes
= insbytes
;
1774 Lisp_Object deletion
;
1782 int range_length
= to
- from
;
1783 prepare_to_modify_buffer (from
, to
, &from
);
1784 to
= from
+ range_length
;
1789 /* Make args be valid */
1795 from_byte
= CHAR_TO_BYTE (from
);
1796 to_byte
= CHAR_TO_BYTE (to
);
1798 nchars_del
= to
- from
;
1799 nbytes_del
= to_byte
- from_byte
;
1801 if (nbytes_del
<= 0 && insbytes
== 0)
1804 /* Make OUTGOING_INSBYTES describe the text
1805 as it will be inserted in this buffer. */
1807 if (NILP (current_buffer
->enable_multibyte_characters
))
1808 outgoing_insbytes
= inschars
;
1809 else if (! STRING_MULTIBYTE (new))
1811 = count_size_as_multibyte (XSTRING (new)->data
, insbytes
);
1813 /* Make sure point-max won't overflow after this insertion. */
1814 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1815 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1816 error ("Maximum buffer size exceeded");
1820 /* Make sure the gap is somewhere in or next to what we are deleting. */
1822 gap_right (from
, from_byte
);
1824 gap_left (to
, to_byte
, 0);
1826 /* Even if we don't record for undo, we must keep the original text
1827 because we may have to recover it because of inappropriate byte
1829 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1832 /* Relocate all markers pointing into the new, larger gap
1833 to point at the end of the text before the gap.
1834 Do this before recording the deletion,
1835 so that undo handles this after reinserting the text. */
1836 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1838 GAP_SIZE
+= nbytes_del
;
1841 ZV_BYTE
-= nbytes_del
;
1842 Z_BYTE
-= nbytes_del
;
1844 GPT_BYTE
= from_byte
;
1845 *(GPT_ADDR
) = 0; /* Put an anchor. */
1850 if (GPT
- BEG
< BEG_UNCHANGED
)
1851 BEG_UNCHANGED
= GPT
- BEG
;
1852 if (Z
- GPT
< END_UNCHANGED
)
1853 END_UNCHANGED
= Z
- GPT
;
1855 if (GAP_SIZE
< insbytes
)
1856 make_gap (insbytes
- GAP_SIZE
);
1858 /* Copy the string text into the buffer, perhaps converting
1859 between single-byte and multibyte. */
1860 copy_text (XSTRING (new)->data
, GPT_ADDR
, insbytes
,
1861 STRING_MULTIBYTE (new),
1862 ! NILP (current_buffer
->enable_multibyte_characters
));
1864 /* We have copied text into the gap, but we have not marked
1865 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1866 here, for both the previous text and the following text.
1867 Meanwhile, GPT_ADDR does point to
1868 the text that has been stored by copy_text. */
1870 combined_before_bytes
1871 = count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
);
1872 combined_after_bytes
1873 = count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
);
1875 if ((combined_before_bytes
&& from
== BEGV
)
1876 || (combined_after_bytes
&& from
== ZV
))
1878 /* Bytes are being combined across the region boundary. We
1879 should avoid it. We recover the original contents before
1880 signaling an error. */
1881 bcopy (XSTRING (deletion
)->data
, GPT_ADDR
, nbytes_del
);
1882 GAP_SIZE
-= nbytes_del
;
1885 ZV_BYTE
+= nbytes_del
;
1886 Z_BYTE
+= nbytes_del
;
1887 GPT
= from
+ nchars_del
;
1888 GPT_BYTE
= from_byte
+ nbytes_del
;
1889 *(GPT_ADDR
) = 0; /* Put an anchor. */
1891 adjust_markers_for_insert (from
, from_byte
, to
, to_byte
, 0, 0, 0);
1893 byte_combining_error ();
1897 /* Record deletion of the surrounding text that combines with
1898 the insertion. This, together with recording the insertion,
1899 will add up to the right stuff in the undo list.
1901 But there is no need to actually delete the combining bytes
1902 from the buffer and reinsert them. */
1904 if (combined_after_bytes
)
1906 Lisp_Object deletion
;
1909 if (! EQ (current_buffer
->undo_list
, Qt
))
1910 deletion
= make_buffer_string_both (from
, from_byte
,
1911 from
+ combined_after_bytes
,
1912 from_byte
+ combined_after_bytes
,
1915 adjust_markers_for_record_delete (from
, from_byte
,
1916 from
+ combined_after_bytes
,
1917 from_byte
+ combined_after_bytes
);
1918 if (! EQ (current_buffer
->undo_list
, Qt
))
1919 record_delete (from
+ nchars_del
, deletion
);
1922 if (combined_before_bytes
)
1924 Lisp_Object deletion
;
1927 if (! EQ (current_buffer
->undo_list
, Qt
))
1928 deletion
= make_buffer_string_both (from
- 1, CHAR_TO_BYTE (from
- 1),
1929 from
, from_byte
, 1);
1930 adjust_markers_for_record_delete (from
- 1, CHAR_TO_BYTE (from
- 1),
1932 if (! EQ (current_buffer
->undo_list
, Qt
))
1933 record_delete (from
- 1, deletion
);
1936 if (! EQ (current_buffer
->undo_list
, Qt
))
1938 record_delete (from
- !!combined_before_bytes
, deletion
);
1939 record_insert (from
- !!combined_before_bytes
,
1940 (inschars
- combined_before_bytes
1941 + !!combined_before_bytes
));
1944 GAP_SIZE
-= outgoing_insbytes
;
1948 GPT_BYTE
+= outgoing_insbytes
;
1949 ZV_BYTE
+= outgoing_insbytes
;
1950 Z_BYTE
+= outgoing_insbytes
;
1951 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1953 if (combined_after_bytes
)
1954 move_gap_both (GPT
+ combined_after_bytes
,
1955 GPT_BYTE
+ combined_after_bytes
);
1960 /* Adjust the overlay center as needed. This must be done after
1961 adjusting the markers that bound the overlays. */
1962 adjust_overlays_for_delete (from
, nchars_del
);
1963 adjust_overlays_for_insert (from
, inschars
);
1965 adjust_markers_for_insert (from
, from_byte
,
1966 from
+ inschars
, from_byte
+ outgoing_insbytes
,
1967 combined_before_bytes
, combined_after_bytes
, 0);
1969 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1971 /* Get the intervals for the part of the string we are inserting--
1972 not including the combined-before bytes. */
1973 intervals
= XSTRING (new)->intervals
;
1974 /* Insert those intervals. */
1975 graft_intervals_into_buffer (intervals
, from
, inschars
,
1976 current_buffer
, inherit
);
1978 /* Relocate point as if it were a marker. */
1980 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1981 (from_byte
+ outgoing_insbytes
1982 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1984 if (combined_after_bytes
)
1986 if (combined_before_bytes
== outgoing_insbytes
)
1987 /* This is the case that all new bytes are combined. */
1988 combined_before_bytes
+= combined_after_bytes
;
1990 combine_bytes (from
+ inschars
, from_byte
+ outgoing_insbytes
,
1991 combined_after_bytes
);
1993 if (combined_before_bytes
)
1994 combine_bytes (from
, from_byte
, combined_before_bytes
);
1996 /* As byte combining will decrease Z, we must check this again. */
1997 if (Z
- GPT
< END_UNCHANGED
)
1998 END_UNCHANGED
= Z
- GPT
;
2000 if (outgoing_insbytes
== 0)
2001 evaporate_overlays (from
);
2008 signal_after_change (from
, nchars_del
, GPT
- from
);
2009 update_compositions (from
, GPT
, CHECK_BORDER
);
2012 /* Delete characters in current buffer
2013 from FROM up to (but not including) TO.
2014 If TO comes before FROM, we delete nothing. */
2017 del_range (from
, to
)
2018 register int from
, to
;
2020 del_range_1 (from
, to
, 1, 0);
2023 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
2024 RET_STRING says to return the deleted text. */
2027 del_range_1 (from
, to
, prepare
, ret_string
)
2028 int from
, to
, prepare
, ret_string
;
2030 int from_byte
, to_byte
;
2031 Lisp_Object deletion
;
2032 struct gcpro gcpro1
;
2034 /* Make args be valid */
2045 int range_length
= to
- from
;
2046 prepare_to_modify_buffer (from
, to
, &from
);
2047 to
= from
+ range_length
;
2050 from_byte
= CHAR_TO_BYTE (from
);
2051 to_byte
= CHAR_TO_BYTE (to
);
2053 deletion
= del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
);
2055 signal_after_change (from
, to
- from
, 0);
2056 update_compositions (from
, from
, CHECK_HEAD
);
2061 /* Like del_range_1 but args are byte positions, not char positions. */
2064 del_range_byte (from_byte
, to_byte
, prepare
)
2065 int from_byte
, to_byte
, prepare
;
2069 /* Make args be valid */
2070 if (from_byte
< BEGV_BYTE
)
2071 from_byte
= BEGV_BYTE
;
2072 if (to_byte
> ZV_BYTE
)
2075 if (to_byte
<= from_byte
)
2078 from
= BYTE_TO_CHAR (from_byte
);
2079 to
= BYTE_TO_CHAR (to_byte
);
2083 int old_from
= from
, old_to
= Z
- to
;
2084 int range_length
= to
- from
;
2085 prepare_to_modify_buffer (from
, to
, &from
);
2086 to
= from
+ range_length
;
2088 if (old_from
!= from
)
2089 from_byte
= CHAR_TO_BYTE (from
);
2090 if (old_to
== Z
- to
)
2091 to_byte
= CHAR_TO_BYTE (to
);
2094 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
2095 signal_after_change (from
, to
- from
, 0);
2096 update_compositions (from
, from
, CHECK_HEAD
);
2099 /* Like del_range_1, but positions are specified both as charpos
2103 del_range_both (from
, from_byte
, to
, to_byte
, prepare
)
2104 int from
, from_byte
, to
, to_byte
, prepare
;
2106 /* Make args be valid */
2107 if (from_byte
< BEGV_BYTE
)
2108 from_byte
= BEGV_BYTE
;
2109 if (to_byte
> ZV_BYTE
)
2112 if (to_byte
<= from_byte
)
2122 int old_from
= from
, old_to
= Z
- to
;
2123 int range_length
= to
- from
;
2124 prepare_to_modify_buffer (from
, to
, &from
);
2125 to
= from
+ range_length
;
2127 if (old_from
!= from
)
2128 from_byte
= CHAR_TO_BYTE (from
);
2129 if (old_to
== Z
- to
)
2130 to_byte
= CHAR_TO_BYTE (to
);
2133 del_range_2 (from
, from_byte
, to
, to_byte
, 0);
2134 signal_after_change (from
, to
- from
, 0);
2135 update_compositions (from
, from
, CHECK_HEAD
);
2138 /* Delete a range of text, specified both as character positions
2139 and byte positions. FROM and TO are character positions,
2140 while FROM_BYTE and TO_BYTE are byte positions.
2141 If RET_STRING is true, the deleted area is returned as a string. */
2144 del_range_2 (from
, from_byte
, to
, to_byte
, ret_string
)
2145 int from
, from_byte
, to
, to_byte
, ret_string
;
2147 register int nbytes_del
, nchars_del
;
2148 int combined_after_bytes
;
2149 Lisp_Object deletion
;
2154 nchars_del
= to
- from
;
2155 nbytes_del
= to_byte
- from_byte
;
2157 /* Make sure the gap is somewhere in or next to what we are deleting. */
2159 gap_right (from
, from_byte
);
2161 gap_left (to
, to_byte
, 0);
2163 combined_after_bytes
2164 = count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
2165 Z_BYTE
- to_byte
, from
, from_byte
);
2166 if (combined_after_bytes
)
2168 if (from
== BEGV
|| to
== ZV
)
2169 byte_combining_error ();
2170 from_byte_1
= from_byte
;
2171 DEC_POS (from_byte_1
);
2174 from_byte_1
= from_byte
;
2176 if (ret_string
|| ! EQ (current_buffer
->undo_list
, Qt
))
2178 = make_buffer_string_both (from
- !!combined_after_bytes
,
2180 to
+ combined_after_bytes
,
2181 to_byte
+ combined_after_bytes
, 1);
2185 if (combined_after_bytes
)
2186 /* COMBINED_AFTER_BYTES nonzero means that the above code moved
2187 the gap. We must move the gap again to a proper place. */
2188 move_gap_both (from
, from_byte
);
2190 /* Relocate all markers pointing into the new, larger gap
2191 to point at the end of the text before the gap.
2192 Do this before recording the deletion,
2193 so that undo handles this after reinserting the text. */
2194 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
2195 if (combined_after_bytes
)
2197 /* Adjust markers for the phony deletion
2198 that we are about to call record_undo for. */
2200 /* Here we delete the markers that formerly
2201 pointed at TO ... TO + COMBINED_AFTER_BYTES.
2202 But because of the call to adjust_markers_for_delete, above,
2203 they now point at FROM ... FROM + COMBINED_AFTER_BYTES. */
2204 adjust_markers_for_record_delete (from
, from_byte
,
2205 from
+ combined_after_bytes
,
2206 from_byte
+ combined_after_bytes
);
2208 adjust_markers_for_record_delete (from
- 1, from_byte_1
,
2211 if (! EQ (current_buffer
->undo_list
, Qt
))
2212 record_delete (from
- !!combined_after_bytes
, deletion
);
2215 /* Relocate point as if it were a marker. */
2217 adjust_point (from
- (PT
< to
? PT
: to
),
2218 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
2220 offset_intervals (current_buffer
, from
, - nchars_del
);
2222 /* Adjust the overlay center as needed. This must be done after
2223 adjusting the markers that bound the overlays. */
2224 adjust_overlays_for_delete (from
, nchars_del
);
2226 GAP_SIZE
+= nbytes_del
;
2227 ZV_BYTE
-= nbytes_del
;
2228 Z_BYTE
-= nbytes_del
;
2232 GPT_BYTE
= from_byte
;
2234 if (combined_after_bytes
)
2235 move_gap_both (GPT
+ combined_after_bytes
,
2236 GPT_BYTE
+ combined_after_bytes
);
2238 *(GPT_ADDR
) = 0; /* Put an anchor. */
2243 if (GPT
- BEG
< BEG_UNCHANGED
)
2244 BEG_UNCHANGED
= GPT
- BEG
;
2245 if (Z
- GPT
< END_UNCHANGED
)
2246 END_UNCHANGED
= Z
- GPT
;
2248 if (combined_after_bytes
)
2250 /* Adjust markers for byte combining. As we have already
2251 adjuted markers without concerning byte combining, here we
2252 must concern only byte combining. */
2253 adjust_markers_for_replace (from
, from_byte
, 0, 0, 0, 0,
2254 0, combined_after_bytes
);
2255 combine_bytes (from
, from_byte
, combined_after_bytes
);
2257 record_insert (GPT
- 1, 1);
2259 if (Z
- GPT
< END_UNCHANGED
)
2260 END_UNCHANGED
= Z
- GPT
;
2265 evaporate_overlays (from
);
2270 /* Call this if you're about to change the region of BUFFER from
2271 character positions START to END. This checks the read-only
2272 properties of the region, calls the necessary modification hooks,
2273 and warns the next redisplay that it should pay attention to that
2277 modify_region (buffer
, start
, end
)
2278 struct buffer
*buffer
;
2281 struct buffer
*old_buffer
= current_buffer
;
2283 if (buffer
!= old_buffer
)
2284 set_buffer_internal (buffer
);
2286 prepare_to_modify_buffer (start
, end
, NULL
);
2288 BUF_COMPUTE_UNCHANGED (buffer
, start
- 1, end
);
2290 if (MODIFF
<= SAVE_MODIFF
)
2291 record_first_change ();
2294 buffer
->point_before_scroll
= Qnil
;
2296 if (buffer
!= old_buffer
)
2297 set_buffer_internal (old_buffer
);
2300 /* Check that it is okay to modify the buffer between START and END,
2301 which are char positions.
2303 Run the before-change-function, if any. If intervals are in use,
2304 verify that the text to be modified is not read-only, and call
2305 any modification properties the text may have.
2307 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2308 by holding its value temporarily in a marker. */
2311 prepare_to_modify_buffer (start
, end
, preserve_ptr
)
2315 if (!NILP (current_buffer
->read_only
))
2316 Fbarf_if_buffer_read_only ();
2318 /* Let redisplay consider other windows than selected_window
2319 if modifying another buffer. */
2320 if (XBUFFER (XWINDOW (selected_window
)->buffer
) != current_buffer
)
2321 ++windows_or_buffers_changed
;
2323 if (BUF_INTERVALS (current_buffer
) != 0)
2327 Lisp_Object preserve_marker
;
2328 struct gcpro gcpro1
;
2329 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
2330 GCPRO1 (preserve_marker
);
2331 verify_interval_modification (current_buffer
, start
, end
);
2332 *preserve_ptr
= marker_position (preserve_marker
);
2333 unchain_marker (preserve_marker
);
2337 verify_interval_modification (current_buffer
, start
, end
);
2340 #ifdef CLASH_DETECTION
2341 if (!NILP (current_buffer
->file_truename
)
2342 /* Make binding buffer-file-name to nil effective. */
2343 && !NILP (current_buffer
->filename
)
2344 && SAVE_MODIFF
>= MODIFF
)
2345 lock_file (current_buffer
->file_truename
);
2347 /* At least warn if this file has changed on disk since it was visited. */
2348 if (!NILP (current_buffer
->filename
)
2349 && SAVE_MODIFF
>= MODIFF
2350 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2351 && !NILP (Ffile_exists_p (current_buffer
->filename
)))
2352 call1 (intern ("ask-user-about-supersession-threat"),
2353 current_buffer
->filename
);
2354 #endif /* not CLASH_DETECTION */
2356 signal_before_change (start
, end
, preserve_ptr
);
2358 if (current_buffer
->newline_cache
)
2359 invalidate_region_cache (current_buffer
,
2360 current_buffer
->newline_cache
,
2361 start
- BEG
, Z
- end
);
2362 if (current_buffer
->width_run_cache
)
2363 invalidate_region_cache (current_buffer
,
2364 current_buffer
->width_run_cache
,
2365 start
- BEG
, Z
- end
);
2367 Vdeactivate_mark
= Qt
;
2370 /* These macros work with an argument named `preserve_ptr'
2371 and a local variable named `preserve_marker'. */
2373 #define PRESERVE_VALUE \
2374 if (preserve_ptr && NILP (preserve_marker)) \
2375 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2377 #define RESTORE_VALUE \
2378 if (! NILP (preserve_marker)) \
2380 *preserve_ptr = marker_position (preserve_marker); \
2381 unchain_marker (preserve_marker); \
2384 #define PRESERVE_START_END \
2385 if (NILP (start_marker)) \
2386 start_marker = Fcopy_marker (start, Qnil); \
2387 if (NILP (end_marker)) \
2388 end_marker = Fcopy_marker (end, Qnil);
2390 #define FETCH_START \
2391 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2394 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2396 /* Signal a change to the buffer immediately before it happens.
2397 START_INT and END_INT are the bounds of the text to be changed.
2399 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2400 by holding its value temporarily in a marker. */
2403 signal_before_change (start_int
, end_int
, preserve_ptr
)
2404 int start_int
, end_int
;
2407 Lisp_Object start
, end
;
2408 Lisp_Object start_marker
, end_marker
;
2409 Lisp_Object preserve_marker
;
2410 struct gcpro gcpro1
, gcpro2
, gcpro3
;
2412 if (inhibit_modification_hooks
)
2415 start
= make_number (start_int
);
2416 end
= make_number (end_int
);
2417 preserve_marker
= Qnil
;
2418 start_marker
= Qnil
;
2420 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
2422 /* If buffer is unmodified, run a special hook for that case. */
2423 if (SAVE_MODIFF
>= MODIFF
2424 && !NILP (Vfirst_change_hook
)
2425 && !NILP (Vrun_hooks
))
2429 call1 (Vrun_hooks
, Qfirst_change_hook
);
2432 /* Run the before-change-function if any.
2433 We don't bother "binding" this variable to nil
2434 because it is obsolete anyway and new code should not use it. */
2435 if (!NILP (Vbefore_change_function
))
2439 call2 (Vbefore_change_function
, FETCH_START
, FETCH_END
);
2442 /* Now run the before-change-functions if any. */
2443 if (!NILP (Vbefore_change_functions
))
2445 Lisp_Object args
[3];
2446 Lisp_Object before_change_functions
;
2447 Lisp_Object after_change_functions
;
2448 struct gcpro gcpro1
, gcpro2
;
2453 /* "Bind" before-change-functions and after-change-functions
2454 to nil--but in a way that errors don't know about.
2455 That way, if there's an error in them, they will stay nil. */
2456 before_change_functions
= Vbefore_change_functions
;
2457 after_change_functions
= Vafter_change_functions
;
2458 Vbefore_change_functions
= Qnil
;
2459 Vafter_change_functions
= Qnil
;
2460 GCPRO2 (before_change_functions
, after_change_functions
);
2462 /* Actually run the hook functions. */
2463 args
[0] = Qbefore_change_functions
;
2464 args
[1] = FETCH_START
;
2465 args
[2] = FETCH_END
;
2466 run_hook_list_with_args (before_change_functions
, 3, args
);
2468 /* "Unbind" the variables we "bound" to nil. */
2469 Vbefore_change_functions
= before_change_functions
;
2470 Vafter_change_functions
= after_change_functions
;
2474 if (!NILP (current_buffer
->overlays_before
)
2475 || !NILP (current_buffer
->overlays_after
))
2478 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2479 FETCH_START
, FETCH_END
, Qnil
);
2482 if (! NILP (start_marker
))
2483 free_marker (start_marker
);
2484 if (! NILP (end_marker
))
2485 free_marker (end_marker
);
2490 /* Signal a change immediately after it happens.
2491 CHARPOS is the character position of the start of the changed text.
2492 LENDEL is the number of characters of the text before the change.
2493 (Not the whole buffer; just the part that was changed.)
2494 LENINS is the number of characters in that part of the text
2495 after the change. */
2498 signal_after_change (charpos
, lendel
, lenins
)
2499 int charpos
, lendel
, lenins
;
2501 if (inhibit_modification_hooks
)
2504 /* If we are deferring calls to the after-change functions
2505 and there are no before-change functions,
2506 just record the args that we were going to use. */
2507 if (! NILP (Vcombine_after_change_calls
)
2508 && NILP (Vbefore_change_function
) && NILP (Vbefore_change_functions
)
2509 && NILP (current_buffer
->overlays_before
)
2510 && NILP (current_buffer
->overlays_after
))
2514 if (!NILP (combine_after_change_list
)
2515 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2516 Fcombine_after_change_execute ();
2518 elt
= Fcons (make_number (charpos
- BEG
),
2519 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2520 Fcons (make_number (lenins
- lendel
), Qnil
)));
2521 combine_after_change_list
2522 = Fcons (elt
, combine_after_change_list
);
2523 combine_after_change_buffer
= Fcurrent_buffer ();
2528 if (!NILP (combine_after_change_list
))
2529 Fcombine_after_change_execute ();
2531 /* Run the after-change-function if any.
2532 We don't bother "binding" this variable to nil
2533 because it is obsolete anyway and new code should not use it. */
2534 if (!NILP (Vafter_change_function
))
2535 call3 (Vafter_change_function
,
2536 make_number (charpos
), make_number (charpos
+ lenins
),
2537 make_number (lendel
));
2539 if (!NILP (Vafter_change_functions
))
2541 Lisp_Object args
[4];
2542 Lisp_Object before_change_functions
;
2543 Lisp_Object after_change_functions
;
2544 struct gcpro gcpro1
, gcpro2
;
2546 /* "Bind" before-change-functions and after-change-functions
2547 to nil--but in a way that errors don't know about.
2548 That way, if there's an error in them, they will stay nil. */
2549 before_change_functions
= Vbefore_change_functions
;
2550 after_change_functions
= Vafter_change_functions
;
2551 Vbefore_change_functions
= Qnil
;
2552 Vafter_change_functions
= Qnil
;
2553 GCPRO2 (before_change_functions
, after_change_functions
);
2555 /* Actually run the hook functions. */
2556 args
[0] = Qafter_change_functions
;
2557 XSETFASTINT (args
[1], charpos
);
2558 XSETFASTINT (args
[2], charpos
+ lenins
);
2559 XSETFASTINT (args
[3], lendel
);
2560 run_hook_list_with_args (after_change_functions
,
2563 /* "Unbind" the variables we "bound" to nil. */
2564 Vbefore_change_functions
= before_change_functions
;
2565 Vafter_change_functions
= after_change_functions
;
2569 if (!NILP (current_buffer
->overlays_before
)
2570 || !NILP (current_buffer
->overlays_after
))
2571 report_overlay_modification (make_number (charpos
),
2572 make_number (charpos
+ lenins
),
2574 make_number (charpos
),
2575 make_number (charpos
+ lenins
),
2576 make_number (lendel
));
2578 /* After an insertion, call the text properties
2579 insert-behind-hooks or insert-in-front-hooks. */
2581 report_interval_modification (make_number (charpos
),
2582 make_number (charpos
+ lenins
));
2586 Fcombine_after_change_execute_1 (val
)
2589 Vcombine_after_change_calls
= val
;
2593 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2594 Scombine_after_change_execute
, 0, 0, 0,
2595 "This function is for use internally in `combine-after-change-calls'.")
2598 int count
= specpdl_ptr
- specpdl
;
2599 int beg
, end
, change
;
2603 if (NILP (combine_after_change_list
))
2606 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2608 Fset_buffer (combine_after_change_buffer
);
2610 /* # chars unchanged at beginning of buffer. */
2612 /* # chars unchanged at end of buffer. */
2614 /* Total amount of insertion (negative for deletion). */
2617 /* Scan the various individual changes,
2618 accumulating the range info in BEG, END and CHANGE. */
2619 for (tail
= combine_after_change_list
; CONSP (tail
);
2623 int thisbeg
, thisend
, thischange
;
2625 /* Extract the info from the next element. */
2629 thisbeg
= XINT (XCAR (elt
));
2634 thisend
= XINT (XCAR (elt
));
2639 thischange
= XINT (XCAR (elt
));
2641 /* Merge this range into the accumulated range. */
2642 change
+= thischange
;
2649 /* Get the current start and end positions of the range
2650 that was changed. */
2654 /* We are about to handle these, so discard them. */
2655 combine_after_change_list
= Qnil
;
2657 /* Now run the after-change functions for real.
2658 Turn off the flag that defers them. */
2659 record_unwind_protect (Fcombine_after_change_execute_1
,
2660 Vcombine_after_change_calls
);
2661 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2662 update_compositions (begpos
, endpos
, CHECK_ALL
);
2664 return unbind_to (count
, Qnil
);
2670 staticpro (&combine_after_change_list
);
2671 combine_after_change_list
= Qnil
;
2672 combine_after_change_buffer
= Qnil
;
2674 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag
,
2675 "Non-nil means enable debugging checks for invalid marker positions.");
2676 check_markers_debug_flag
= 0;
2677 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls
,
2678 "Used internally by the `combine-after-change-calls' macro.");
2679 Vcombine_after_change_calls
= Qnil
;
2681 DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks
,
2682 "Non-nil means don't run any of the hooks that respond to buffer changes.\n\
2683 This affects `before-change-functions' and `after-change-functions',\n\
2684 as well as hooks attached to text properties and overlays.");
2685 inhibit_modification_hooks
= 0;
2687 defsubr (&Scombine_after_change_execute
);