1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 86, 93, 94, 95, 97, 1998 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))
37 static void insert_from_string_1
P_ ((Lisp_Object
, int, int, int, int, int, int));
38 static void insert_from_buffer_1 ();
39 static void gap_left
P_ ((int, int, int));
40 static void gap_right
P_ ((int, int));
41 static void adjust_markers_gap_motion
P_ ((int, int, int));
42 static void adjust_markers_for_insert
P_ ((int, int, int, int, int, int, int));
43 static void adjust_markers_for_delete
P_ ((int, int, int, int));
44 static void adjust_markers_for_record_delete
P_ ((int, int, int, int));
45 static void adjust_point
P_ ((int, int));
47 Lisp_Object
Fcombine_after_change_execute ();
49 /* Non-nil means don't call the after-change-functions right away,
50 just record an element in Vcombine_after_change_calls_list. */
51 Lisp_Object Vcombine_after_change_calls
;
53 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
54 describing changes which happened while combine_after_change_calls
55 was nonzero. We use this to decide how to call them
56 once the deferral ends.
59 BEG-UNCHANGED is the number of chars before the changed range.
60 END-UNCHANGED is the number of chars after the changed range,
61 and CHANGE-AMOUNT is the number of characters inserted by the change
62 (negative for a deletion). */
63 Lisp_Object combine_after_change_list
;
65 /* Buffer which combine_after_change_list is about. */
66 Lisp_Object combine_after_change_buffer
;
68 /* Check all markers in the current buffer, looking for something invalid. */
70 static int check_markers_debug_flag
;
72 #define CHECK_MARKERS() \
73 if (check_markers_debug_flag) \
80 register Lisp_Object tail
, prev
, next
;
82 tail
= BUF_MARKERS (current_buffer
);
84 while (XSYMBOL (tail
) != XSYMBOL (Qnil
))
86 if (XMARKER (tail
)->buffer
->text
!= current_buffer
->text
)
88 if (XMARKER (tail
)->charpos
> Z
)
90 if (XMARKER (tail
)->bytepos
> Z_BYTE
)
93 tail
= XMARKER (tail
)->chain
;
97 /* Move gap to position CHARPOS.
98 Note that this can quit! */
104 move_gap_both (charpos
, charpos_to_bytepos (charpos
));
107 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
108 Note that this can quit! */
111 move_gap_both (charpos
, bytepos
)
112 int charpos
, bytepos
;
114 if (bytepos
< GPT_BYTE
)
115 gap_left (charpos
, bytepos
, 0);
116 else if (bytepos
> GPT_BYTE
)
117 gap_right (charpos
, bytepos
);
120 /* Move the gap to a position less than the current GPT.
121 BYTEPOS describes the new position as a byte position,
122 and CHARPOS is the corresponding char position.
123 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
126 gap_left (charpos
, bytepos
, newgap
)
127 register int charpos
, bytepos
;
130 register unsigned char *to
, *from
;
136 if (unchanged_modified
== MODIFF
137 && overlay_unchanged_modified
== OVERLAY_MODIFF
)
139 beg_unchanged
= charpos
- BEG
;
140 end_unchanged
= Z
- charpos
;
144 if (Z
- GPT
< end_unchanged
)
145 end_unchanged
= Z
- GPT
;
146 if (charpos
< beg_unchanged
)
147 beg_unchanged
= charpos
- BEG
;
156 /* Now copy the characters. To move the gap down,
157 copy characters up. */
161 /* I gets number of characters left to copy. */
162 i
= new_s1
- bytepos
;
165 /* If a quit is requested, stop copying now.
166 Change BYTEPOS to be where we have actually moved the gap to. */
170 charpos
= BYTE_TO_CHAR (bytepos
);
173 /* Move at most 32000 chars before checking again for a quit. */
178 /* bcopy is safe if the two areas of memory do not overlap
179 or on systems where bcopy is always safe for moving upward. */
180 && (BCOPY_UPWARD_SAFE
181 || to
- from
>= 128))
183 /* If overlap is not safe, avoid it by not moving too many
184 characters at once. */
185 if (!BCOPY_UPWARD_SAFE
&& i
> to
- from
)
200 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
201 BYTEPOS is where the loop above stopped, which may be what was specified
202 or may be where a quit was detected. */
203 adjust_markers_gap_motion (bytepos
, GPT_BYTE
, GAP_SIZE
);
206 if (bytepos
< charpos
)
208 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
212 /* Move the gap to a position greater than than the current GPT.
213 BYTEPOS describes the new position as a byte position,
214 and CHARPOS is the corresponding char position. */
217 gap_right (charpos
, bytepos
)
218 register int charpos
, bytepos
;
220 register unsigned char *to
, *from
;
224 if (unchanged_modified
== MODIFF
225 && overlay_unchanged_modified
== OVERLAY_MODIFF
)
227 beg_unchanged
= charpos
- BEG
;
228 end_unchanged
= Z
- charpos
;
232 if (Z
- charpos
- 1 < end_unchanged
)
233 end_unchanged
= Z
- charpos
;
234 if (GPT
- BEG
< beg_unchanged
)
235 beg_unchanged
= GPT
- BEG
;
243 /* Now copy the characters. To move the gap up,
244 copy characters down. */
248 /* I gets number of characters left to copy. */
249 i
= bytepos
- new_s1
;
252 /* If a quit is requested, stop copying now.
253 Change BYTEPOS to be where we have actually moved the gap to. */
257 charpos
= BYTE_TO_CHAR (bytepos
);
260 /* Move at most 32000 chars before checking again for a quit. */
265 /* bcopy is safe if the two areas of memory do not overlap
266 or on systems where bcopy is always safe for moving downward. */
267 && (BCOPY_DOWNWARD_SAFE
268 || from
- to
>= 128))
270 /* If overlap is not safe, avoid it by not moving too many
271 characters at once. */
272 if (!BCOPY_DOWNWARD_SAFE
&& i
> from
- to
)
287 adjust_markers_gap_motion (GPT_BYTE
+ GAP_SIZE
, bytepos
+ GAP_SIZE
,
291 if (bytepos
< charpos
)
293 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
297 /* Add AMOUNT to the byte position of every marker in the current buffer
298 whose current byte position is between FROM (exclusive) and TO (inclusive).
300 Also, any markers past the outside of that interval, in the direction
301 of adjustment, are first moved back to the near end of the interval
302 and then adjusted by AMOUNT.
304 When the latter adjustment is done, if AMOUNT is negative,
305 we record the adjustment for undo. (This case happens only for
308 The markers' character positions are not altered,
309 because gap motion does not affect character positions. */
311 int adjust_markers_test
;
314 adjust_markers_gap_motion (from
, to
, amount
)
315 register int from
, to
, amount
;
317 /* Now that a marker has a bytepos, not counting the gap,
318 nothing needs to be done here. */
321 register struct Lisp_Marker
*m
;
324 marker
= BUF_MARKERS (current_buffer
);
326 while (!NILP (marker
))
328 m
= XMARKER (marker
);
332 if (mpos
> to
&& mpos
< to
+ amount
)
334 if (adjust_markers_test
)
341 /* Here's the case where a marker is inside text being deleted.
342 AMOUNT can be negative for gap motion, too,
343 but then this range contains no markers. */
344 if (mpos
> from
+ amount
&& mpos
<= from
)
346 if (adjust_markers_test
)
348 mpos
= from
+ amount
;
351 if (mpos
> from
&& mpos
<= to
)
359 /* Adjust all markers for a deletion
360 whose range in bytes is FROM_BYTE to TO_BYTE.
361 The range in charpos is FROM to TO.
363 This function assumes that the gap is adjacent to
364 or inside of the range being deleted. */
367 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
)
368 register int from
, from_byte
, to
, to_byte
;
371 register struct Lisp_Marker
*m
;
372 register int charpos
;
374 marker
= BUF_MARKERS (current_buffer
);
376 while (!NILP (marker
))
378 m
= XMARKER (marker
);
379 charpos
= m
->charpos
;
384 /* If the marker is after the deletion,
385 relocate by number of chars / bytes deleted. */
388 m
->charpos
-= to
- from
;
389 m
->bytepos
-= to_byte
- from_byte
;
392 /* Here's the case where a marker is inside text being deleted. */
393 else if (charpos
> from
)
395 record_marker_adjustment (marker
, from
- charpos
);
397 m
->bytepos
= from_byte
;
405 /* Adjust all markers for calling record_delete for combining bytes.
406 whose range in bytes is FROM_BYTE to TO_BYTE.
407 The range in charpos is FROM to TO. */
410 adjust_markers_for_record_delete (from
, from_byte
, to
, to_byte
)
411 register int from
, from_byte
, to
, to_byte
;
414 register struct Lisp_Marker
*m
;
415 register int charpos
;
417 marker
= BUF_MARKERS (current_buffer
);
419 while (!NILP (marker
))
421 m
= XMARKER (marker
);
422 charpos
= m
->charpos
;
424 /* If the marker is after the deletion,
425 relocate by number of chars / bytes deleted. */
428 /* Here's the case where a marker is inside text being deleted. */
429 else if (charpos
> from
)
430 record_marker_adjustment (marker
, from
- charpos
);
436 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
437 to TO / TO_BYTE. We have to relocate the charpos of every marker
438 that points after the insertion (but not their bytepos).
440 COMBINED_BEFORE_BYTES is the number of bytes at the start of the insertion
441 that combine into one character with the text before the insertion.
442 COMBINED_AFTER_BYTES is the number of bytes after the insertion
443 that combine into one character with the last inserted bytes.
445 When a marker points at the insertion point,
446 we advance it if either its insertion-type is t
447 or BEFORE_MARKERS is true. */
450 adjust_markers_for_insert (from
, from_byte
, to
, to_byte
,
451 combined_before_bytes
, combined_after_bytes
,
453 register int from
, from_byte
, to
, to_byte
;
454 int combined_before_bytes
, combined_after_bytes
, before_markers
;
458 int nchars
= to
- from
;
459 int nbytes
= to_byte
- from_byte
;
461 marker
= BUF_MARKERS (current_buffer
);
463 while (!NILP (marker
))
465 register struct Lisp_Marker
*m
= XMARKER (marker
);
467 /* In a single-byte buffer, a marker's two positions must be equal.
468 (If this insertion is going to combine characters, Z will
469 become different from Z_BYTE, but they might be the same now.
470 If so, the two OLD positions of the marker should be equal.) */
473 if (m
->charpos
!= m
->bytepos
)
477 if (m
->bytepos
== from_byte
)
479 if (m
->insertion_type
|| before_markers
)
481 m
->bytepos
+= nbytes
+ combined_after_bytes
;
482 m
->charpos
+= nchars
+ !!combined_after_bytes
;
483 /* Point the marker before the combined character,
484 so that undoing the insertion puts it back where it was. */
485 if (combined_after_bytes
)
486 DEC_BOTH (m
->charpos
, m
->bytepos
);
487 if (m
->insertion_type
)
490 else if (combined_before_bytes
)
492 /* This marker doesn't "need relocation",
493 but don't leave it pointing in the middle of a character.
494 Point the marker after the combined character,
495 so that undoing the insertion puts it back where it was. */
497 /* Here we depend on the fact that the gap is after
498 all of the combining bytes that we are going to skip over. */
499 DEC_BOTH (m
->charpos
, m
->bytepos
);
500 INC_BOTH (m
->charpos
, m
->bytepos
);
503 /* If a marker was pointing into the combining bytes
504 after the insertion, don't leave it there
505 in the middle of a character. */
506 else if (combined_after_bytes
&& m
->bytepos
>= from_byte
507 && m
->bytepos
< from_byte
+ combined_after_bytes
)
509 /* Put it after the combining bytes. */
510 m
->bytepos
= to_byte
+ combined_after_bytes
;
512 /* Now move it back before the combined character,
513 so that undoing the insertion will put it where it was. */
514 DEC_BOTH (m
->charpos
, m
->bytepos
);
516 else if (m
->bytepos
> from_byte
)
518 m
->bytepos
+= nbytes
;
519 m
->charpos
+= nchars
;
525 /* Adjusting only markers whose insertion-type is t may result in
526 disordered overlays in the slot `overlays_before'. */
528 fix_overlays_before (current_buffer
, from
, to
);
531 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
533 This is used only when the value of point changes due to an insert
534 or delete; it does not represent a conceptual change in point as a
535 marker. In particular, point is not crossing any interval
536 boundaries, so there's no need to use the usual SET_PT macro. In
537 fact it would be incorrect to do so, because either the old or the
538 new value of point is out of sync with the current set of
542 adjust_point (nchars
, nbytes
)
545 BUF_PT (current_buffer
) += nchars
;
546 BUF_PT_BYTE (current_buffer
) += nbytes
;
548 /* In a single-byte buffer, the two positions must be equal. */
554 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
555 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
558 See the comment of adjust_markers_for_insert for the args
559 COMBINED_BEFORE_BYTES and COMBINED_AFTER_BYTES. */
562 adjust_markers_for_replace (from
, from_byte
, old_chars
, old_bytes
,
563 new_chars
, new_bytes
,
564 combined_before_bytes
, combined_after_bytes
)
565 int from
, from_byte
, old_chars
, old_bytes
, new_chars
, new_bytes
;
566 int combined_before_bytes
, combined_after_bytes
;
568 Lisp_Object marker
= BUF_MARKERS (current_buffer
);
569 int prev_to_byte
= from_byte
+ old_bytes
;
571 = (new_chars
- combined_before_bytes
) - (old_chars
+ combined_after_bytes
);
572 int diff_bytes
= new_bytes
- old_bytes
;
574 while (!NILP (marker
))
576 register struct Lisp_Marker
*m
= XMARKER (marker
);
578 if (m
->bytepos
>= prev_to_byte
)
580 if (m
->bytepos
< prev_to_byte
+ combined_after_bytes
)
582 /* Put it after the combining bytes. */
583 m
->bytepos
= from_byte
+ new_bytes
+ combined_after_bytes
;
584 m
->charpos
= from
+ new_chars
- combined_before_bytes
;
588 m
->charpos
+= diff_chars
;
589 m
->bytepos
+= diff_bytes
;
592 else if (m
->bytepos
>= from_byte
)
595 m
->bytepos
= from_byte
+ combined_before_bytes
;
596 /* If all new bytes are combined in addition to that there
597 are after combining bytes, we must set byte position of
598 the marker after the after combining bytes. */
599 if (combined_before_bytes
== new_bytes
)
600 m
->bytepos
+= combined_after_bytes
;
610 /* Make the gap NBYTES_ADDED bytes longer. */
613 make_gap (nbytes_added
)
616 unsigned char *result
;
619 int real_gap_loc_byte
;
622 /* If we have to get more space, get enough to last a while. */
623 nbytes_added
+= 2000;
625 /* Don't allow a buffer size that won't fit in an int
626 even if it will fit in a Lisp integer.
627 That won't work because so many places use `int'. */
629 if (Z_BYTE
- BEG_BYTE
+ GAP_SIZE
+ nbytes_added
630 >= ((unsigned) 1 << (min (BITS_PER_INT
, VALBITS
) - 1)))
631 error ("Buffer exceeds maximum size");
634 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */
635 result
= BUFFER_REALLOC (BEG_ADDR
, (Z_BYTE
- BEG_BYTE
636 + GAP_SIZE
+ nbytes_added
+ 1));
644 /* We can't unblock until the new address is properly stored. */
648 /* Prevent quitting in move_gap. */
653 real_gap_loc_byte
= GPT_BYTE
;
654 old_gap_size
= GAP_SIZE
;
656 /* Call the newly allocated space a gap at the end of the whole space. */
658 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
659 GAP_SIZE
= nbytes_added
;
661 /* Move the new gap down to be consecutive with the end of the old one.
662 This adjusts the markers properly too. */
663 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
665 /* Now combine the two into one large gap. */
666 GAP_SIZE
+= old_gap_size
;
668 GPT_BYTE
= real_gap_loc_byte
;
676 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
677 FROM_MULTIBYTE says whether the incoming text is multibyte.
678 TO_MULTIBYTE says whether to store the text as multibyte.
679 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
681 Return the number of bytes stored at TO_ADDR. */
684 copy_text (from_addr
, to_addr
, nbytes
,
685 from_multibyte
, to_multibyte
)
686 unsigned char *from_addr
;
687 unsigned char *to_addr
;
689 int from_multibyte
, to_multibyte
;
691 if (from_multibyte
== to_multibyte
)
693 bcopy (from_addr
, to_addr
, nbytes
);
696 else if (from_multibyte
)
699 int bytes_left
= nbytes
;
700 Lisp_Object tbl
= Qnil
, temp
;
702 /* We set the variable tbl to the reverse table of
703 Vnonascii_translation_table in advance. */
704 if (CHAR_TABLE_P (Vnonascii_translation_table
))
706 tbl
= Fchar_table_extra_slot (Vnonascii_translation_table
,
708 if (!CHAR_TABLE_P (tbl
))
712 /* Convert multibyte to single byte. */
713 while (bytes_left
> 0)
715 int thislen
, c
, c_save
;
716 c
= c_save
= STRING_CHAR_AND_LENGTH (from_addr
, bytes_left
, thislen
);
717 if (!SINGLE_BYTE_CHAR_P (c
))
718 c
= multibyte_char_to_unibyte (c
, tbl
);
720 from_addr
+= thislen
;
721 bytes_left
-= thislen
;
728 unsigned char *initial_to_addr
= to_addr
;
730 /* Convert single-byte to multibyte. */
733 int c
= *from_addr
++;
734 unsigned char workbuf
[4], *str
;
737 if ((c
>= 0240 || !NILP (Vnonascii_translation_table
)) && c
< 0400)
739 c
= unibyte_char_to_multibyte (c
);
740 len
= CHAR_STRING (c
, workbuf
, str
);
741 bcopy (str
, to_addr
, len
);
746 /* Special case for speed. */
747 *to_addr
++ = c
, nbytes
--;
749 return to_addr
- initial_to_addr
;
753 /* Return the number of bytes it would take
754 to convert some single-byte text to multibyte.
755 The single-byte text consists of NBYTES bytes at PTR. */
758 count_size_as_multibyte (ptr
, nbytes
)
763 int outgoing_nbytes
= 0;
765 for (i
= 0; i
< nbytes
; i
++)
767 unsigned int c
= *ptr
++;
769 if (c
< 0240 && NILP (Vnonascii_translation_table
))
773 c
= unibyte_char_to_multibyte (c
);
774 outgoing_nbytes
+= CHAR_BYTES (c
);
778 return outgoing_nbytes
;
781 /* Insert a string of specified length before point.
782 This function judges multibyteness based on
783 enable_multibyte_characters in the current buffer;
784 it never converts between single-byte and multibyte.
786 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
787 prepare_to_modify_buffer could relocate the text. */
790 insert (string
, nbytes
)
791 register unsigned char *string
;
797 insert_1 (string
, nbytes
, 0, 1, 0);
798 signal_after_change (opoint
, 0, PT
- opoint
);
802 /* Likewise, but inherit text properties from neighboring characters. */
805 insert_and_inherit (string
, nbytes
)
806 register unsigned char *string
;
812 insert_1 (string
, nbytes
, 1, 1, 0);
813 signal_after_change (opoint
, 0, PT
- opoint
);
817 /* Insert the character C before point. Do not inherit text properties. */
823 unsigned char workbuf
[4], *str
;
826 if (! NILP (current_buffer
->enable_multibyte_characters
))
827 len
= CHAR_STRING (c
, workbuf
, str
);
838 /* Insert the null-terminated string S before point. */
844 insert (s
, strlen (s
));
847 /* Like `insert' except that all markers pointing at the place where
848 the insertion happens are adjusted to point after it.
849 Don't use this function to insert part of a Lisp string,
850 since gc could happen and relocate it. */
853 insert_before_markers (string
, nbytes
)
854 unsigned char *string
;
861 insert_1 (string
, nbytes
, 0, 1, 1);
862 signal_after_change (opoint
, 0, PT
- opoint
);
866 /* Likewise, but inherit text properties from neighboring characters. */
869 insert_before_markers_and_inherit (string
, nbytes
)
870 unsigned char *string
;
877 insert_1 (string
, nbytes
, 1, 1, 1);
878 signal_after_change (opoint
, 0, PT
- opoint
);
882 /* Subroutine used by the insert functions above. */
885 insert_1 (string
, nbytes
, inherit
, prepare
, before_markers
)
886 register unsigned char *string
;
888 int inherit
, prepare
, before_markers
;
890 insert_1_both (string
, chars_in_text (string
, nbytes
), nbytes
,
891 inherit
, prepare
, before_markers
);
894 /* See if the bytes before POS/POS_BYTE combine with bytes
895 at the start of STRING to form a single character.
896 If so, return the number of bytes at the start of STRING
897 which combine in this way. Otherwise, return 0. */
900 count_combining_before (string
, length
, pos
, pos_byte
)
901 unsigned char *string
;
905 int opos
= pos
, opos_byte
= pos_byte
;
907 unsigned char *p
= string
;
909 if (NILP (current_buffer
->enable_multibyte_characters
))
911 if (length
== 0 || CHAR_HEAD_P (*string
))
915 c
= FETCH_BYTE (pos_byte
- 1);
916 if (ASCII_BYTE_P (c
))
918 DEC_BOTH (pos
, pos_byte
);
919 c
= FETCH_BYTE (pos_byte
);
920 if (! BASE_LEADING_CODE_P (c
))
923 /* We have a combination situation.
924 Count the bytes at STRING that will combine. */
925 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
931 /* See if the bytes after POS/POS_BYTE combine with bytes
932 at the end of STRING to form a single character.
933 If so, return the number of bytes after POS/POS_BYTE
934 which combine in this way. Otherwise, return 0. */
937 count_combining_after (string
, length
, pos
, pos_byte
)
938 unsigned char *string
;
942 int opos
= pos
, opos_byte
= pos_byte
;
946 if (NILP (current_buffer
->enable_multibyte_characters
))
948 if (length
== 0 || ASCII_BYTE_P (string
[length
- 1]))
951 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
957 /* All characters in `string' are not character head.
958 We must check also preceding bytes at POS.
959 We are sure that the gap is at POS. */
962 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
964 if (i
< 0 || !BASE_LEADING_CODE_P (string
[i
]))
967 else if (!BASE_LEADING_CODE_P (string
[i
]))
972 c
= FETCH_BYTE (pos_byte
);
975 while (pos_byte
< ZV_BYTE
)
977 c
= FETCH_BYTE (pos_byte
);
983 return pos_byte
- opos_byte
;
986 /* Adjust the position TARGET/TARGET_BYTE for the combining of NBYTES
987 following the position POS/POS_BYTE to the character preceding POS.
988 If TARGET is after POS+NBYTES, we only have to adjust the character
989 position TARGET, else, if TARGET is after POS, we have to adjust
990 both the character position TARGET and the byte position
991 TARGET_BYTE, else we don't have to do any adjustment. */
993 #define ADJUST_CHAR_POS(target, target_byte) \
995 if (target > pos + nbytes) \
997 else if (target >= pos) \
1000 target_byte = pos_byte + nbytes; \
1004 /* Combine NBYTES stray trailing-codes, which were formerly separate
1005 characters, with the preceding character. These bytes
1006 are located after position POS / POS_BYTE, and the preceding character
1007 is located just before that position.
1009 This function does not adjust markers for byte combining. That
1010 should be done in advance by the functions
1011 adjust_markers_for_insert, adjust_markers_for_delete, or
1012 adjust_markers_for_replace. */
1015 combine_bytes (pos
, pos_byte
, nbytes
)
1016 int pos
, pos_byte
, nbytes
;
1018 adjust_overlays_for_delete (pos
, nbytes
);
1020 ADJUST_CHAR_POS (BUF_PT (current_buffer
), BUF_PT_BYTE (current_buffer
));
1021 ADJUST_CHAR_POS (GPT
, GPT_BYTE
);
1022 ADJUST_CHAR_POS (Z
, Z_BYTE
);
1023 ADJUST_CHAR_POS (ZV
, ZV_BYTE
);
1025 if (BUF_INTERVALS (current_buffer
) != 0)
1026 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
1027 offset_intervals (current_buffer
, pos
, - nbytes
);
1030 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1031 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
1032 are the same as in insert_1. */
1035 insert_1_both (string
, nchars
, nbytes
, inherit
, prepare
, before_markers
)
1036 register unsigned char *string
;
1037 register int nchars
, nbytes
;
1038 int inherit
, prepare
, before_markers
;
1040 register Lisp_Object temp
;
1041 int combined_before_bytes
, combined_after_bytes
;
1043 if (NILP (current_buffer
->enable_multibyte_characters
))
1047 /* Do this before moving and increasing the gap,
1048 because the before-change hooks might move the gap
1049 or make it smaller. */
1050 prepare_to_modify_buffer (PT
, PT
, NULL
);
1053 move_gap_both (PT
, PT_BYTE
);
1054 if (GAP_SIZE
< nbytes
)
1055 make_gap (nbytes
- GAP_SIZE
);
1057 combined_before_bytes
1058 = count_combining_before (string
, nbytes
, PT
, PT_BYTE
);
1059 combined_after_bytes
1060 = count_combining_after (string
, nbytes
, PT
, PT_BYTE
);
1062 /* Record deletion of the surrounding text that combines with
1063 the insertion. This, together with recording the insertion,
1064 will add up to the right stuff in the undo list.
1066 But there is no need to actually delete the combining bytes
1067 from the buffer and reinsert them. */
1069 if (combined_after_bytes
)
1071 Lisp_Object deletion
;
1074 if (! EQ (current_buffer
->undo_list
, Qt
))
1075 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1076 PT
+ combined_after_bytes
,
1077 PT_BYTE
+ combined_after_bytes
, 1);
1079 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1080 PT
+ combined_after_bytes
,
1081 PT_BYTE
+ combined_after_bytes
);
1082 if (! EQ (current_buffer
->undo_list
, Qt
))
1083 record_delete (PT
, deletion
);
1086 if (combined_before_bytes
)
1088 Lisp_Object deletion
;
1091 if (! EQ (current_buffer
->undo_list
, Qt
))
1092 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1094 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1096 if (! EQ (current_buffer
->undo_list
, Qt
))
1097 record_delete (PT
- 1, deletion
);
1100 record_insert (PT
- !!combined_before_bytes
,
1101 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1104 bcopy (string
, GPT_ADDR
, nbytes
);
1107 /* When we have combining at the end of the insertion,
1108 this is the character position before the combined character. */
1115 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1117 if (combined_after_bytes
)
1118 move_gap_both (GPT
+ combined_after_bytes
,
1119 GPT_BYTE
+ combined_after_bytes
);
1124 adjust_overlays_for_insert (PT
, nchars
);
1125 adjust_markers_for_insert (PT
, PT_BYTE
,
1126 PT
+ nchars
, PT_BYTE
+ nbytes
,
1127 combined_before_bytes
, combined_after_bytes
,
1130 #ifdef USE_TEXT_PROPERTIES
1131 if (BUF_INTERVALS (current_buffer
) != 0)
1132 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
1133 offset_intervals (current_buffer
, PT
, nchars
);
1135 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
1136 Fset_text_properties (make_number (PT
), make_number (PT
+ nchars
),
1141 int pos
= PT
, pos_byte
= PT_BYTE
;
1143 adjust_point (nchars
+ combined_after_bytes
,
1144 nbytes
+ combined_after_bytes
);
1146 if (combined_after_bytes
)
1147 combine_bytes (pos
+ nchars
, pos_byte
+ nbytes
, combined_after_bytes
);
1149 if (combined_before_bytes
)
1150 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1154 /* Insert the part of the text of STRING, a Lisp object assumed to be
1155 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1156 starting at position POS / POS_BYTE. If the text of STRING has properties,
1157 copy them into the buffer.
1159 It does not work to use `insert' for this, because a GC could happen
1160 before we bcopy the stuff into the buffer, and relocate the string
1161 without insert noticing. */
1164 insert_from_string (string
, pos
, pos_byte
, length
, length_byte
, inherit
)
1166 register int pos
, pos_byte
, length
, length_byte
;
1170 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1172 signal_after_change (opoint
, 0, PT
- opoint
);
1175 /* Like `insert_from_string' except that all markers pointing
1176 at the place where the insertion happens are adjusted to point after it. */
1179 insert_from_string_before_markers (string
, pos
, pos_byte
,
1180 length
, length_byte
, inherit
)
1182 register int pos
, pos_byte
, length
, length_byte
;
1186 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1188 signal_after_change (opoint
, 0, PT
- opoint
);
1191 /* Subroutine of the insertion functions above. */
1194 insert_from_string_1 (string
, pos
, pos_byte
, nchars
, nbytes
,
1195 inherit
, before_markers
)
1197 register int pos
, pos_byte
, nchars
, nbytes
;
1198 int inherit
, before_markers
;
1200 register Lisp_Object temp
;
1201 struct gcpro gcpro1
;
1202 int outgoing_nbytes
= nbytes
;
1203 int combined_before_bytes
, combined_after_bytes
;
1204 int adjusted_nchars
;
1207 /* Make OUTGOING_NBYTES describe the text
1208 as it will be inserted in this buffer. */
1210 if (NILP (current_buffer
->enable_multibyte_characters
))
1211 outgoing_nbytes
= nchars
;
1212 else if (! STRING_MULTIBYTE (string
))
1214 = count_size_as_multibyte (&XSTRING (string
)->data
[pos_byte
],
1218 /* Do this before moving and increasing the gap,
1219 because the before-change hooks might move the gap
1220 or make it smaller. */
1221 prepare_to_modify_buffer (PT
, PT
, NULL
);
1224 move_gap_both (PT
, PT_BYTE
);
1225 if (GAP_SIZE
< nbytes
)
1226 make_gap (outgoing_nbytes
- GAP_SIZE
);
1229 /* Copy the string text into the buffer, perhaps converting
1230 between single-byte and multibyte. */
1231 copy_text (XSTRING (string
)->data
+ pos_byte
, GPT_ADDR
, nbytes
,
1232 STRING_MULTIBYTE (string
),
1233 ! NILP (current_buffer
->enable_multibyte_characters
));
1235 /* We have copied text into the gap, but we have not altered
1236 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1237 to these functions and get the same results as we would
1238 have got earlier on. Meanwhile, PT_ADDR does point to
1239 the text that has been stored by copy_text. */
1241 combined_before_bytes
1242 = count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1243 combined_after_bytes
1244 = count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1246 /* Record deletion of the surrounding text that combines with
1247 the insertion. This, together with recording the insertion,
1248 will add up to the right stuff in the undo list.
1250 But there is no need to actually delete the combining bytes
1251 from the buffer and reinsert them. */
1253 if (combined_after_bytes
)
1255 Lisp_Object deletion
;
1258 if (! EQ (current_buffer
->undo_list
, Qt
))
1259 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1260 PT
+ combined_after_bytes
,
1261 PT_BYTE
+ combined_after_bytes
, 1);
1263 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1264 PT
+ combined_after_bytes
,
1265 PT_BYTE
+ combined_after_bytes
);
1266 if (! EQ (current_buffer
->undo_list
, Qt
))
1267 record_delete (PT
, deletion
);
1270 if (combined_before_bytes
)
1272 Lisp_Object deletion
;
1275 if (! EQ (current_buffer
->undo_list
, Qt
))
1276 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1278 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1280 if (! EQ (current_buffer
->undo_list
, Qt
))
1281 record_delete (PT
- 1, deletion
);
1284 record_insert (PT
- !!combined_before_bytes
,
1285 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1288 GAP_SIZE
-= outgoing_nbytes
;
1292 GPT_BYTE
+= outgoing_nbytes
;
1293 ZV_BYTE
+= outgoing_nbytes
;
1294 Z_BYTE
+= outgoing_nbytes
;
1295 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1297 if (combined_after_bytes
)
1298 move_gap_both (GPT
+ combined_after_bytes
,
1299 GPT_BYTE
+ combined_after_bytes
);
1304 adjust_overlays_for_insert (PT
, nchars
);
1305 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1306 PT_BYTE
+ outgoing_nbytes
,
1307 combined_before_bytes
, combined_after_bytes
,
1310 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1311 offset_intervals (current_buffer
, PT
, nchars
);
1313 intervals
= XSTRING (string
)->intervals
;
1314 /* Get the intervals for the part of the string we are inserting--
1315 not including the combined-before bytes. */
1316 if (nbytes
< STRING_BYTES (XSTRING (string
)))
1317 intervals
= copy_intervals (intervals
, pos
, nchars
);
1319 /* Insert those intervals. */
1320 graft_intervals_into_buffer (intervals
, PT
, nchars
,
1321 current_buffer
, inherit
);
1324 int pos
= PT
, pos_byte
= PT_BYTE
;
1326 adjust_point (nchars
+ combined_after_bytes
,
1327 outgoing_nbytes
+ combined_after_bytes
);
1329 if (combined_after_bytes
)
1330 combine_bytes (pos
+ nchars
, pos_byte
+ outgoing_nbytes
,
1331 combined_after_bytes
);
1333 if (combined_before_bytes
)
1334 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1338 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1339 current buffer. If the text in BUF has properties, they are absorbed
1340 into the current buffer.
1342 It does not work to use `insert' for this, because a malloc could happen
1343 and relocate BUF's text before the bcopy happens. */
1346 insert_from_buffer (buf
, charpos
, nchars
, inherit
)
1348 int charpos
, nchars
;
1353 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1354 signal_after_change (opoint
, 0, PT
- opoint
);
1358 insert_from_buffer_1 (buf
, from
, nchars
, inherit
)
1363 register Lisp_Object temp
;
1365 int from_byte
= buf_charpos_to_bytepos (buf
, from
);
1366 int to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1367 int incoming_nbytes
= to_byte
- from_byte
;
1368 int outgoing_nbytes
= incoming_nbytes
;
1369 int combined_before_bytes
, combined_after_bytes
;
1370 int adjusted_nchars
;
1373 /* Make OUTGOING_NBYTES describe the text
1374 as it will be inserted in this buffer. */
1376 if (NILP (current_buffer
->enable_multibyte_characters
))
1377 outgoing_nbytes
= nchars
;
1378 else if (NILP (buf
->enable_multibyte_characters
))
1380 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1383 /* Make sure point-max won't overflow after this insertion. */
1384 XSETINT (temp
, outgoing_nbytes
+ Z
);
1385 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1386 error ("Maximum buffer size exceeded");
1388 /* Do this before moving and increasing the gap,
1389 because the before-change hooks might move the gap
1390 or make it smaller. */
1391 prepare_to_modify_buffer (PT
, PT
, NULL
);
1394 move_gap_both (PT
, PT_BYTE
);
1395 if (GAP_SIZE
< outgoing_nbytes
)
1396 make_gap (outgoing_nbytes
- GAP_SIZE
);
1398 if (from
< BUF_GPT (buf
))
1400 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1401 if (chunk
> incoming_nbytes
)
1402 chunk
= incoming_nbytes
;
1403 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1405 ! NILP (buf
->enable_multibyte_characters
),
1406 ! NILP (current_buffer
->enable_multibyte_characters
));
1410 if (chunk
< incoming_nbytes
)
1411 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1412 GPT_ADDR
+ chunk
, incoming_nbytes
- chunk
,
1413 ! NILP (buf
->enable_multibyte_characters
),
1414 ! NILP (current_buffer
->enable_multibyte_characters
));
1416 /* We have copied text into the gap, but we have not altered
1417 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1418 to these functions and get the same results as we would
1419 have got earlier on. Meanwhile, GPT_ADDR does point to
1420 the text that has been stored by copy_text. */
1421 combined_before_bytes
1422 = count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1423 combined_after_bytes
1424 = count_combining_after (GPT_ADDR
, outgoing_nbytes
,
1427 /* Record deletion of the surrounding text that combines with
1428 the insertion. This, together with recording the insertion,
1429 will add up to the right stuff in the undo list.
1431 But there is no need to actually delete the combining bytes
1432 from the buffer and reinsert them. */
1434 if (combined_after_bytes
)
1436 Lisp_Object deletion
;
1439 if (! EQ (current_buffer
->undo_list
, Qt
))
1440 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1441 PT
+ combined_after_bytes
,
1442 PT_BYTE
+ combined_after_bytes
, 1);
1444 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1445 PT
+ combined_after_bytes
,
1446 PT_BYTE
+ combined_after_bytes
);
1447 if (! EQ (current_buffer
->undo_list
, Qt
))
1448 record_delete (PT
, deletion
);
1451 if (combined_before_bytes
)
1453 Lisp_Object deletion
;
1456 if (! EQ (current_buffer
->undo_list
, Qt
))
1457 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1459 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1461 if (! EQ (current_buffer
->undo_list
, Qt
))
1462 record_delete (PT
- 1, deletion
);
1465 record_insert (PT
- !!combined_before_bytes
,
1466 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1469 GAP_SIZE
-= outgoing_nbytes
;
1473 GPT_BYTE
+= outgoing_nbytes
;
1474 ZV_BYTE
+= outgoing_nbytes
;
1475 Z_BYTE
+= outgoing_nbytes
;
1476 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1478 if (combined_after_bytes
)
1479 move_gap_both (GPT
+ combined_after_bytes
,
1480 GPT_BYTE
+ combined_after_bytes
);
1485 adjust_overlays_for_insert (PT
, nchars
);
1486 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1487 PT_BYTE
+ outgoing_nbytes
,
1488 combined_before_bytes
, combined_after_bytes
, 0);
1490 #ifdef USE_TEXT_PROPERTIES
1491 if (BUF_INTERVALS (current_buffer
) != 0)
1492 offset_intervals (current_buffer
, PT
, nchars
);
1495 /* Get the intervals for the part of the string we are inserting--
1496 not including the combined-before bytes. */
1497 intervals
= BUF_INTERVALS (buf
);
1498 if (outgoing_nbytes
< BUF_Z_BYTE (buf
) - BUF_BEG_BYTE (buf
))
1499 intervals
= copy_intervals (intervals
, from
, nchars
);
1501 /* Insert those intervals. */
1502 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1505 int pos
= PT
, pos_byte
= PT_BYTE
;
1507 adjust_point (nchars
+ combined_after_bytes
,
1508 outgoing_nbytes
+ combined_after_bytes
);
1510 if (combined_after_bytes
)
1511 combine_bytes (pos
+ nchars
, pos_byte
+ outgoing_nbytes
,
1512 combined_after_bytes
);
1514 if (combined_before_bytes
)
1515 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1519 /* This function should be called after moving gap to FROM and before
1520 altering text between FROM and TO. This adjusts various position
1521 keepers and markers as if the text is deleted. Don't forget to
1522 call adjust_after_replace after you actually alter the text. */
1525 adjust_before_replace (from
, from_byte
, to
, to_byte
)
1526 int from
, from_byte
, to
, to_byte
;
1528 Lisp_Object deletion
;
1530 if (! EQ (current_buffer
->undo_list
, Qt
))
1531 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1535 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1537 if (! EQ (current_buffer
->undo_list
, Qt
))
1538 record_delete (from
, deletion
);
1540 adjust_overlays_for_delete (from
, to
- from
);
1543 /* Record undo information and adjust markers and position keepers for
1544 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1545 chars (LEN_BYTE bytes) which resides in the gap just after
1548 PREV_TEXT nil means the new text was just inserted. */
1551 adjust_after_replace (from
, from_byte
, prev_text
, len
, len_byte
)
1552 int from
, from_byte
, len
, len_byte
;
1553 Lisp_Object prev_text
;
1555 int combined_before_bytes
1556 = count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
);
1557 int combined_after_bytes
1558 = count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
);
1559 int nchars_del
= 0, nbytes_del
= 0;
1561 if (combined_after_bytes
)
1563 Lisp_Object deletion
;
1566 if (! EQ (current_buffer
->undo_list
, Qt
))
1567 deletion
= make_buffer_string_both (from
, from_byte
,
1568 from
+ combined_after_bytes
,
1569 from_byte
+ combined_after_bytes
,
1572 adjust_markers_for_record_delete (from
, from_byte
,
1573 from
+ combined_after_bytes
,
1574 from_byte
+ combined_after_bytes
);
1576 if (! EQ (current_buffer
->undo_list
, Qt
))
1577 record_delete (from
+ len
, deletion
);
1580 if (combined_before_bytes
)
1582 Lisp_Object deletion
;
1585 if (! EQ (current_buffer
->undo_list
, Qt
))
1586 deletion
= make_buffer_string_both (from
- 1, CHAR_TO_BYTE (from
- 1),
1587 from
, from_byte
, 1);
1588 adjust_markers_for_record_delete (from
- 1, CHAR_TO_BYTE (from
- 1),
1590 if (! EQ (current_buffer
->undo_list
, Qt
))
1591 record_delete (from
- 1, deletion
);
1594 /* Update various buffer positions for the new text. */
1595 GAP_SIZE
-= len_byte
;
1597 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1598 GPT
+= len
; GPT_BYTE
+= len_byte
;
1599 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1601 if (combined_after_bytes
)
1602 move_gap_both (GPT
+ combined_after_bytes
,
1603 GPT_BYTE
+ combined_after_bytes
);
1605 if (STRINGP (prev_text
))
1607 nchars_del
= XSTRING (prev_text
)->size
;
1608 nbytes_del
= STRING_BYTES (XSTRING (prev_text
));
1610 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1612 combined_before_bytes
, combined_after_bytes
);
1613 if (STRINGP (prev_text
))
1614 record_delete (from
- !!combined_before_bytes
, prev_text
);
1615 record_insert (from
- !!combined_before_bytes
,
1616 len
- combined_before_bytes
+ !!combined_before_bytes
);
1618 if (len
> nchars_del
)
1619 adjust_overlays_for_insert (from
, len
- nchars_del
);
1620 else if (len
< nchars_del
)
1621 adjust_overlays_for_delete (from
, nchars_del
- len
);
1622 #ifdef USE_TEXT_PROPERTIES
1623 if (BUF_INTERVALS (current_buffer
) != 0)
1625 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1630 int pos
= PT
, pos_byte
= PT_BYTE
;
1633 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1635 if (combined_after_bytes
)
1637 if (combined_before_bytes
)
1638 combined_before_bytes
+= combined_after_bytes
;
1640 combine_bytes (from
+ len
, from_byte
+ len_byte
,
1641 combined_after_bytes
);
1644 if (combined_before_bytes
)
1645 combine_bytes (from
, from_byte
, combined_before_bytes
);
1651 evaporate_overlays (from
);
1655 /* Record undo information, adjust markers and position keepers for an
1656 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1657 text already exists in the current buffer but character length (TO
1658 - FROM) may be incorrect, the correct length is NEWLEN. */
1661 adjust_after_insert (from
, from_byte
, to
, to_byte
, newlen
)
1662 int from
, from_byte
, to
, to_byte
, newlen
;
1664 int len
= to
- from
, len_byte
= to_byte
- from_byte
;
1667 move_gap_both (to
, to_byte
);
1668 GAP_SIZE
+= len_byte
;
1669 GPT
-= len
; GPT_BYTE
-= len_byte
;
1670 ZV
-= len
; ZV_BYTE
-= len_byte
;
1671 Z
-= len
; Z_BYTE
-= len_byte
;
1672 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1675 /* Replace the text from character positions FROM to TO with NEW,
1676 If PREPARE is nonzero, call prepare_to_modify_buffer.
1677 If INHERIT, the newly inserted text should inherit text properties
1678 from the surrounding non-deleted text. */
1680 /* Note that this does not yet handle markers quite right.
1681 Also it needs to record a single undo-entry that does a replacement
1682 rather than a separate delete and insert.
1683 That way, undo will also handle markers properly.
1685 But if MARKERS is 0, don't relocate markers. */
1688 replace_range (from
, to
, new, prepare
, inherit
, markers
)
1690 int from
, to
, prepare
, inherit
, markers
;
1692 int inschars
= XSTRING (new)->size
;
1693 int insbytes
= STRING_BYTES (XSTRING (new));
1694 int from_byte
, to_byte
;
1695 int nbytes_del
, nchars_del
;
1696 register Lisp_Object temp
;
1697 struct gcpro gcpro1
;
1698 int combined_before_bytes
, combined_after_bytes
;
1699 int adjusted_inschars
;
1701 int outgoing_insbytes
= insbytes
;
1702 Lisp_Object deletion
;
1710 int range_length
= to
- from
;
1711 prepare_to_modify_buffer (from
, to
, &from
);
1712 to
= from
+ range_length
;
1717 /* Make args be valid */
1723 from_byte
= CHAR_TO_BYTE (from
);
1724 to_byte
= CHAR_TO_BYTE (to
);
1726 nchars_del
= to
- from
;
1727 nbytes_del
= to_byte
- from_byte
;
1729 if (nbytes_del
<= 0 && insbytes
== 0)
1732 /* Make OUTGOING_INSBYTES describe the text
1733 as it will be inserted in this buffer. */
1735 if (NILP (current_buffer
->enable_multibyte_characters
))
1736 outgoing_insbytes
= inschars
;
1737 else if (! STRING_MULTIBYTE (new))
1739 = count_size_as_multibyte (XSTRING (new)->data
, insbytes
);
1741 /* Make sure point-max won't overflow after this insertion. */
1742 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1743 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1744 error ("Maximum buffer size exceeded");
1748 /* Make sure the gap is somewhere in or next to what we are deleting. */
1750 gap_right (from
, from_byte
);
1752 gap_left (to
, to_byte
, 0);
1756 if (! EQ (current_buffer
->undo_list
, Qt
))
1757 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1760 /* Relocate all markers pointing into the new, larger gap
1761 to point at the end of the text before the gap.
1762 Do this before recording the deletion,
1763 so that undo handles this after reinserting the text. */
1764 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1766 GAP_SIZE
+= nbytes_del
;
1769 ZV_BYTE
-= nbytes_del
;
1770 Z_BYTE
-= nbytes_del
;
1772 GPT_BYTE
= from_byte
;
1773 *(GPT_ADDR
) = 0; /* Put an anchor. */
1778 if (GPT
- BEG
< beg_unchanged
)
1779 beg_unchanged
= GPT
- BEG
;
1780 if (Z
- GPT
< end_unchanged
)
1781 end_unchanged
= Z
- GPT
;
1783 if (GAP_SIZE
< insbytes
)
1784 make_gap (insbytes
- GAP_SIZE
);
1786 /* Copy the string text into the buffer, perhaps converting
1787 between single-byte and multibyte. */
1788 copy_text (XSTRING (new)->data
, GPT_ADDR
, insbytes
,
1789 STRING_MULTIBYTE (new),
1790 ! NILP (current_buffer
->enable_multibyte_characters
));
1792 /* We have copied text into the gap, but we have not marked
1793 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1794 here, for both the previous text and the following text.
1795 Meanwhile, GPT_ADDR does point to
1796 the text that has been stored by copy_text. */
1798 combined_before_bytes
1799 = count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
);
1800 combined_after_bytes
1801 = count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
);
1803 /* Record deletion of the surrounding text that combines with
1804 the insertion. This, together with recording the insertion,
1805 will add up to the right stuff in the undo list.
1807 But there is no need to actually delete the combining bytes
1808 from the buffer and reinsert them. */
1810 if (combined_after_bytes
)
1812 Lisp_Object deletion
;
1815 if (! EQ (current_buffer
->undo_list
, Qt
))
1816 deletion
= make_buffer_string_both (from
, from_byte
,
1817 from
+ combined_after_bytes
,
1818 from_byte
+ combined_after_bytes
, 1);
1820 adjust_markers_for_record_delete (from
, from_byte
,
1821 from
+ combined_after_bytes
,
1822 from_byte
+ combined_after_bytes
);
1823 if (! EQ (current_buffer
->undo_list
, Qt
))
1824 record_delete (from
+ inschars
, deletion
);
1827 if (combined_before_bytes
)
1829 Lisp_Object deletion
;
1832 if (! EQ (current_buffer
->undo_list
, Qt
))
1833 deletion
= make_buffer_string_both (from
- 1, CHAR_TO_BYTE (from
- 1),
1834 from
, from_byte
, 1);
1835 adjust_markers_for_record_delete (from
- 1, CHAR_TO_BYTE (from
- 1),
1837 if (! EQ (current_buffer
->undo_list
, Qt
))
1838 record_delete (from
- 1, deletion
);
1841 if (! EQ (current_buffer
->undo_list
, Qt
))
1843 record_delete (from
- !!combined_before_bytes
, deletion
);
1844 record_insert (from
- !!combined_before_bytes
,
1845 (inschars
- combined_before_bytes
1846 + !!combined_before_bytes
));
1849 GAP_SIZE
-= outgoing_insbytes
;
1853 GPT_BYTE
+= outgoing_insbytes
;
1854 ZV_BYTE
+= outgoing_insbytes
;
1855 Z_BYTE
+= outgoing_insbytes
;
1856 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1858 if (combined_after_bytes
)
1859 move_gap_both (GPT
+ combined_after_bytes
,
1860 GPT_BYTE
+ combined_after_bytes
);
1865 /* Adjust the overlay center as needed. This must be done after
1866 adjusting the markers that bound the overlays. */
1867 adjust_overlays_for_delete (from
, nchars_del
);
1868 adjust_overlays_for_insert (from
, inschars
);
1870 adjust_markers_for_insert (from
, from_byte
,
1871 from
+ inschars
, from_byte
+ outgoing_insbytes
,
1872 combined_before_bytes
, combined_after_bytes
, 0);
1874 #ifdef USE_TEXT_PROPERTIES
1875 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1877 /* Get the intervals for the part of the string we are inserting--
1878 not including the combined-before bytes. */
1879 intervals
= XSTRING (new)->intervals
;
1880 /* Insert those intervals. */
1881 graft_intervals_into_buffer (intervals
, from
, inschars
,
1882 current_buffer
, inherit
);
1885 /* Relocate point as if it were a marker. */
1887 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1888 (from_byte
+ outgoing_insbytes
1889 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1891 if (combined_after_bytes
)
1893 if (combined_before_bytes
)
1894 combined_before_bytes
+= combined_after_bytes
;
1896 combine_bytes (from
+ inschars
, from_byte
+ outgoing_insbytes
,
1897 combined_after_bytes
);
1899 if (combined_before_bytes
)
1900 combine_bytes (from
, from_byte
, combined_before_bytes
);
1902 if (outgoing_insbytes
== 0)
1903 evaporate_overlays (from
);
1910 signal_after_change (from
, nchars_del
, GPT
- from
);
1913 /* Delete characters in current buffer
1914 from FROM up to (but not including) TO.
1915 If TO comes before FROM, we delete nothing. */
1918 del_range (from
, to
)
1919 register int from
, to
;
1921 del_range_1 (from
, to
, 1);
1924 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
1927 del_range_1 (from
, to
, prepare
)
1928 int from
, to
, prepare
;
1930 int from_byte
, to_byte
;
1932 /* Make args be valid */
1943 int range_length
= to
- from
;
1944 prepare_to_modify_buffer (from
, to
, &from
);
1945 to
= from
+ range_length
;
1948 from_byte
= CHAR_TO_BYTE (from
);
1949 to_byte
= CHAR_TO_BYTE (to
);
1951 del_range_2 (from
, from_byte
, to
, to_byte
);
1954 /* Like del_range_1 but args are byte positions, not char positions. */
1957 del_range_byte (from_byte
, to_byte
, prepare
)
1958 int from_byte
, to_byte
, prepare
;
1962 /* Make args be valid */
1963 if (from_byte
< BEGV_BYTE
)
1964 from_byte
= BEGV_BYTE
;
1965 if (to_byte
> ZV_BYTE
)
1968 if (to_byte
<= from_byte
)
1971 from
= BYTE_TO_CHAR (from_byte
);
1972 to
= BYTE_TO_CHAR (to_byte
);
1976 int old_from
= from
, old_to
= Z
- to
;
1977 int range_length
= to
- from
;
1978 prepare_to_modify_buffer (from
, to
, &from
);
1979 to
= from
+ range_length
;
1981 if (old_from
!= from
)
1982 from_byte
= CHAR_TO_BYTE (from
);
1983 if (old_to
== Z
- to
)
1984 to_byte
= CHAR_TO_BYTE (to
);
1987 del_range_2 (from
, from_byte
, to
, to_byte
);
1990 /* Like del_range_1, but positions are specified both as charpos
1994 del_range_both (from
, from_byte
, to
, to_byte
, prepare
)
1995 int from
, from_byte
, to
, to_byte
, prepare
;
1997 /* Make args be valid */
1998 if (from_byte
< BEGV_BYTE
)
1999 from_byte
= BEGV_BYTE
;
2000 if (to_byte
> ZV_BYTE
)
2003 if (to_byte
<= from_byte
)
2013 int old_from
= from
, old_to
= Z
- to
;
2014 int range_length
= to
- from
;
2015 prepare_to_modify_buffer (from
, to
, &from
);
2016 to
= from
+ range_length
;
2018 if (old_from
!= from
)
2019 from_byte
= CHAR_TO_BYTE (from
);
2020 if (old_to
== Z
- to
)
2021 to_byte
= CHAR_TO_BYTE (to
);
2024 del_range_2 (from
, from_byte
, to
, to_byte
);
2027 /* Delete a range of text, specified both as character positions
2028 and byte positions. FROM and TO are character positions,
2029 while FROM_BYTE and TO_BYTE are byte positions. */
2032 del_range_2 (from
, from_byte
, to
, to_byte
)
2033 int from
, from_byte
, to
, to_byte
;
2035 register int nbytes_del
, nchars_del
;
2036 int combined_after_bytes
;
2037 Lisp_Object deletion
;
2042 nchars_del
= to
- from
;
2043 nbytes_del
= to_byte
- from_byte
;
2045 /* Make sure the gap is somewhere in or next to what we are deleting. */
2047 gap_right (from
, from_byte
);
2049 gap_left (to
, to_byte
, 0);
2051 combined_after_bytes
2052 = count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
2053 ZV_BYTE
- to_byte
, from
, from_byte
);
2054 if (combined_after_bytes
)
2056 from_byte_1
= from_byte
;
2057 DEC_POS (from_byte_1
);
2060 from_byte_1
= from_byte
;
2062 if (! EQ (current_buffer
->undo_list
, Qt
))
2064 = make_buffer_string_both (from
- !!combined_after_bytes
,
2066 to
+ combined_after_bytes
,
2067 to_byte
+ combined_after_bytes
, 1);
2068 if (combined_after_bytes
)
2069 /* COMBINED_AFTER_BYTES nonzero means that the above code moved
2070 the gap. We must move the gap again to a proper place. */
2071 move_gap_both (from
, from_byte
);
2073 /* Relocate all markers pointing into the new, larger gap
2074 to point at the end of the text before the gap.
2075 Do this before recording the deletion,
2076 so that undo handles this after reinserting the text. */
2077 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
2078 if (combined_after_bytes
)
2080 /* Adjust markers for the phony deletion
2081 that we are about to call record_undo for. */
2083 /* Here we delete the markers that formerly
2084 pointed at TO ... TO + COMBINED_AFTER_BYTES.
2085 But because of the call to adjust_markers_for_delete, above,
2086 they now point at FROM ... FROM + COMBINED_AFTER_BYTES. */
2087 adjust_markers_for_record_delete (from
, from_byte
,
2088 from
+ combined_after_bytes
,
2089 from_byte
+ combined_after_bytes
);
2091 adjust_markers_for_record_delete (from
- 1, from_byte_1
,
2094 if (! EQ (current_buffer
->undo_list
, Qt
))
2095 record_delete (from
- !!combined_after_bytes
, deletion
);
2098 /* Relocate point as if it were a marker. */
2100 adjust_point (from
- (PT
< to
? PT
: to
),
2101 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
2103 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
2104 offset_intervals (current_buffer
, from
, - nchars_del
);
2106 /* Adjust the overlay center as needed. This must be done after
2107 adjusting the markers that bound the overlays. */
2108 adjust_overlays_for_delete (from
, nchars_del
);
2110 GAP_SIZE
+= nbytes_del
;
2111 ZV_BYTE
-= nbytes_del
;
2112 Z_BYTE
-= nbytes_del
;
2116 GPT_BYTE
= from_byte
;
2118 if (combined_after_bytes
)
2119 move_gap_both (GPT
+ combined_after_bytes
,
2120 GPT_BYTE
+ combined_after_bytes
);
2122 *(GPT_ADDR
) = 0; /* Put an anchor. */
2127 if (GPT
- BEG
< beg_unchanged
)
2128 beg_unchanged
= GPT
- BEG
;
2129 if (Z
- GPT
< end_unchanged
)
2130 end_unchanged
= Z
- GPT
;
2132 if (combined_after_bytes
)
2134 combine_bytes (from
, from_byte
, combined_after_bytes
);
2136 record_insert (GPT
- 1, 1);
2141 evaporate_overlays (from
);
2142 signal_after_change (from
, nchars_del
, 0);
2145 /* Call this if you're about to change the region of BUFFER from
2146 character positions START to END. This checks the read-only
2147 properties of the region, calls the necessary modification hooks,
2148 and warns the next redisplay that it should pay attention to that
2152 modify_region (buffer
, start
, end
)
2153 struct buffer
*buffer
;
2156 struct buffer
*old_buffer
= current_buffer
;
2158 if (buffer
!= old_buffer
)
2159 set_buffer_internal (buffer
);
2161 prepare_to_modify_buffer (start
, end
, NULL
);
2163 if (start
- 1 < beg_unchanged
2164 || (unchanged_modified
== MODIFF
2165 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
2166 beg_unchanged
= start
- 1;
2167 if (Z
- end
< end_unchanged
2168 || (unchanged_modified
== MODIFF
2169 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
2170 end_unchanged
= Z
- end
;
2172 if (MODIFF
<= SAVE_MODIFF
)
2173 record_first_change ();
2176 buffer
->point_before_scroll
= Qnil
;
2178 if (buffer
!= old_buffer
)
2179 set_buffer_internal (old_buffer
);
2182 /* Check that it is okay to modify the buffer between START and END,
2183 which are char positions.
2185 Run the before-change-function, if any. If intervals are in use,
2186 verify that the text to be modified is not read-only, and call
2187 any modification properties the text may have.
2189 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2190 by holding its value temporarily in a marker. */
2193 prepare_to_modify_buffer (start
, end
, preserve_ptr
)
2197 if (!NILP (current_buffer
->read_only
))
2198 Fbarf_if_buffer_read_only ();
2200 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
2201 if (BUF_INTERVALS (current_buffer
) != 0)
2205 Lisp_Object preserve_marker
;
2206 struct gcpro gcpro1
;
2207 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
2208 GCPRO1 (preserve_marker
);
2209 verify_interval_modification (current_buffer
, start
, end
);
2210 *preserve_ptr
= marker_position (preserve_marker
);
2211 unchain_marker (preserve_marker
);
2215 verify_interval_modification (current_buffer
, start
, end
);
2218 #ifdef CLASH_DETECTION
2219 if (!NILP (current_buffer
->file_truename
)
2220 /* Make binding buffer-file-name to nil effective. */
2221 && !NILP (current_buffer
->filename
)
2222 && SAVE_MODIFF
>= MODIFF
)
2223 lock_file (current_buffer
->file_truename
);
2225 /* At least warn if this file has changed on disk since it was visited. */
2226 if (!NILP (current_buffer
->filename
)
2227 && SAVE_MODIFF
>= MODIFF
2228 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2229 && !NILP (Ffile_exists_p (current_buffer
->filename
)))
2230 call1 (intern ("ask-user-about-supersession-threat"),
2231 current_buffer
->filename
);
2232 #endif /* not CLASH_DETECTION */
2234 signal_before_change (start
, end
, preserve_ptr
);
2236 if (current_buffer
->newline_cache
)
2237 invalidate_region_cache (current_buffer
,
2238 current_buffer
->newline_cache
,
2239 start
- BEG
, Z
- end
);
2240 if (current_buffer
->width_run_cache
)
2241 invalidate_region_cache (current_buffer
,
2242 current_buffer
->width_run_cache
,
2243 start
- BEG
, Z
- end
);
2245 Vdeactivate_mark
= Qt
;
2248 /* These macros work with an argument named `preserve_ptr'
2249 and a local variable named `preserve_marker'. */
2251 #define PRESERVE_VALUE \
2252 if (preserve_ptr && NILP (preserve_marker)) \
2253 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2255 #define RESTORE_VALUE \
2256 if (! NILP (preserve_marker)) \
2258 *preserve_ptr = marker_position (preserve_marker); \
2259 unchain_marker (preserve_marker); \
2262 #define PRESERVE_START_END \
2263 if (NILP (start_marker)) \
2264 start_marker = Fcopy_marker (start, Qnil); \
2265 if (NILP (end_marker)) \
2266 end_marker = Fcopy_marker (end, Qnil);
2268 #define FETCH_START \
2269 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2272 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2274 /* Signal a change to the buffer immediately before it happens.
2275 START_INT and END_INT are the bounds of the text to be changed.
2277 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2278 by holding its value temporarily in a marker. */
2281 signal_before_change (start_int
, end_int
, preserve_ptr
)
2282 int start_int
, end_int
;
2285 Lisp_Object start
, end
;
2286 Lisp_Object start_marker
, end_marker
;
2287 Lisp_Object preserve_marker
;
2288 struct gcpro gcpro1
, gcpro2
, gcpro3
;
2290 if (inhibit_modification_hooks
)
2293 start
= make_number (start_int
);
2294 end
= make_number (end_int
);
2295 preserve_marker
= Qnil
;
2296 start_marker
= Qnil
;
2298 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
2300 /* If buffer is unmodified, run a special hook for that case. */
2301 if (SAVE_MODIFF
>= MODIFF
2302 && !NILP (Vfirst_change_hook
)
2303 && !NILP (Vrun_hooks
))
2307 call1 (Vrun_hooks
, Qfirst_change_hook
);
2310 /* Run the before-change-function if any.
2311 We don't bother "binding" this variable to nil
2312 because it is obsolete anyway and new code should not use it. */
2313 if (!NILP (Vbefore_change_function
))
2317 call2 (Vbefore_change_function
, FETCH_START
, FETCH_END
);
2320 /* Now run the before-change-functions if any. */
2321 if (!NILP (Vbefore_change_functions
))
2323 Lisp_Object args
[3];
2324 Lisp_Object before_change_functions
;
2325 Lisp_Object after_change_functions
;
2326 struct gcpro gcpro1
, gcpro2
;
2331 /* "Bind" before-change-functions and after-change-functions
2332 to nil--but in a way that errors don't know about.
2333 That way, if there's an error in them, they will stay nil. */
2334 before_change_functions
= Vbefore_change_functions
;
2335 after_change_functions
= Vafter_change_functions
;
2336 Vbefore_change_functions
= Qnil
;
2337 Vafter_change_functions
= Qnil
;
2338 GCPRO2 (before_change_functions
, after_change_functions
);
2340 /* Actually run the hook functions. */
2341 args
[0] = Qbefore_change_functions
;
2342 args
[1] = FETCH_START
;
2343 args
[2] = FETCH_END
;
2344 run_hook_list_with_args (before_change_functions
, 3, args
);
2346 /* "Unbind" the variables we "bound" to nil. */
2347 Vbefore_change_functions
= before_change_functions
;
2348 Vafter_change_functions
= after_change_functions
;
2352 if (!NILP (current_buffer
->overlays_before
)
2353 || !NILP (current_buffer
->overlays_after
))
2356 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2357 FETCH_START
, FETCH_END
, Qnil
);
2360 if (! NILP (start_marker
))
2361 free_marker (start_marker
);
2362 if (! NILP (end_marker
))
2363 free_marker (end_marker
);
2368 /* Signal a change immediately after it happens.
2369 CHARPOS is the character position of the start of the changed text.
2370 LENDEL is the number of characters of the text before the change.
2371 (Not the whole buffer; just the part that was changed.)
2372 LENINS is the number of characters in that part of the text
2373 after the change. */
2376 signal_after_change (charpos
, lendel
, lenins
)
2377 int charpos
, lendel
, lenins
;
2379 if (inhibit_modification_hooks
)
2382 /* If we are deferring calls to the after-change functions
2383 and there are no before-change functions,
2384 just record the args that we were going to use. */
2385 if (! NILP (Vcombine_after_change_calls
)
2386 && NILP (Vbefore_change_function
) && NILP (Vbefore_change_functions
)
2387 && NILP (current_buffer
->overlays_before
)
2388 && NILP (current_buffer
->overlays_after
))
2392 if (!NILP (combine_after_change_list
)
2393 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2394 Fcombine_after_change_execute ();
2396 elt
= Fcons (make_number (charpos
- BEG
),
2397 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2398 Fcons (make_number (lenins
- lendel
), Qnil
)));
2399 combine_after_change_list
2400 = Fcons (elt
, combine_after_change_list
);
2401 combine_after_change_buffer
= Fcurrent_buffer ();
2406 if (!NILP (combine_after_change_list
))
2407 Fcombine_after_change_execute ();
2409 /* Run the after-change-function if any.
2410 We don't bother "binding" this variable to nil
2411 because it is obsolete anyway and new code should not use it. */
2412 if (!NILP (Vafter_change_function
))
2413 call3 (Vafter_change_function
,
2414 make_number (charpos
), make_number (charpos
+ lenins
),
2415 make_number (lendel
));
2417 if (!NILP (Vafter_change_functions
))
2419 Lisp_Object args
[4];
2420 Lisp_Object before_change_functions
;
2421 Lisp_Object after_change_functions
;
2422 struct gcpro gcpro1
, gcpro2
;
2424 /* "Bind" before-change-functions and after-change-functions
2425 to nil--but in a way that errors don't know about.
2426 That way, if there's an error in them, they will stay nil. */
2427 before_change_functions
= Vbefore_change_functions
;
2428 after_change_functions
= Vafter_change_functions
;
2429 Vbefore_change_functions
= Qnil
;
2430 Vafter_change_functions
= Qnil
;
2431 GCPRO2 (before_change_functions
, after_change_functions
);
2433 /* Actually run the hook functions. */
2434 args
[0] = Qafter_change_functions
;
2435 XSETFASTINT (args
[1], charpos
);
2436 XSETFASTINT (args
[2], charpos
+ lenins
);
2437 XSETFASTINT (args
[3], lendel
);
2438 run_hook_list_with_args (after_change_functions
,
2441 /* "Unbind" the variables we "bound" to nil. */
2442 Vbefore_change_functions
= before_change_functions
;
2443 Vafter_change_functions
= after_change_functions
;
2447 if (!NILP (current_buffer
->overlays_before
)
2448 || !NILP (current_buffer
->overlays_after
))
2449 report_overlay_modification (make_number (charpos
),
2450 make_number (charpos
+ lenins
),
2452 make_number (charpos
),
2453 make_number (charpos
+ lenins
),
2454 make_number (lendel
));
2456 /* After an insertion, call the text properties
2457 insert-behind-hooks or insert-in-front-hooks. */
2459 report_interval_modification (make_number (charpos
),
2460 make_number (charpos
+ lenins
));
2464 Fcombine_after_change_execute_1 (val
)
2467 Vcombine_after_change_calls
= val
;
2471 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2472 Scombine_after_change_execute
, 0, 0, 0,
2473 "This function is for use internally in `combine-after-change-calls'.")
2476 register Lisp_Object val
;
2477 int count
= specpdl_ptr
- specpdl
;
2478 int beg
, end
, change
;
2482 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2484 Fset_buffer (combine_after_change_buffer
);
2486 /* # chars unchanged at beginning of buffer. */
2488 /* # chars unchanged at end of buffer. */
2490 /* Total amount of insertion (negative for deletion). */
2493 /* Scan the various individual changes,
2494 accumulating the range info in BEG, END and CHANGE. */
2495 for (tail
= combine_after_change_list
; CONSP (tail
);
2496 tail
= XCONS (tail
)->cdr
)
2499 int thisbeg
, thisend
, thischange
;
2501 /* Extract the info from the next element. */
2502 elt
= XCONS (tail
)->car
;
2505 thisbeg
= XINT (XCONS (elt
)->car
);
2507 elt
= XCONS (elt
)->cdr
;
2510 thisend
= XINT (XCONS (elt
)->car
);
2512 elt
= XCONS (elt
)->cdr
;
2515 thischange
= XINT (XCONS (elt
)->car
);
2517 /* Merge this range into the accumulated range. */
2518 change
+= thischange
;
2525 /* Get the current start and end positions of the range
2526 that was changed. */
2530 /* We are about to handle these, so discard them. */
2531 combine_after_change_list
= Qnil
;
2533 /* Now run the after-change functions for real.
2534 Turn off the flag that defers them. */
2535 record_unwind_protect (Fcombine_after_change_execute_1
,
2536 Vcombine_after_change_calls
);
2537 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2539 return unbind_to (count
, val
);
2545 staticpro (&combine_after_change_list
);
2546 combine_after_change_list
= Qnil
;
2548 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag
,
2549 "Non-nil means enable debugging checks for invalid marker positions.");
2550 check_markers_debug_flag
= 0;
2551 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls
,
2552 "Used internally by the `combine-after-change-calls' macro.");
2553 Vcombine_after_change_calls
= Qnil
;
2555 defsubr (&Scombine_after_change_execute
);