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
;
81 int multibyte
= ! NILP (current_buffer
->enable_multibyte_characters
);
83 tail
= BUF_MARKERS (current_buffer
);
85 while (XSYMBOL (tail
) != XSYMBOL (Qnil
))
87 if (XMARKER (tail
)->buffer
->text
!= current_buffer
->text
)
89 if (XMARKER (tail
)->charpos
> Z
)
91 if (XMARKER (tail
)->bytepos
> Z_BYTE
)
93 if (multibyte
&& ! CHAR_HEAD_P (FETCH_BYTE (XMARKER (tail
)->bytepos
)))
96 tail
= XMARKER (tail
)->chain
;
100 /* Move gap to position CHARPOS.
101 Note that this can quit! */
107 move_gap_both (charpos
, charpos_to_bytepos (charpos
));
110 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
111 Note that this can quit! */
114 move_gap_both (charpos
, bytepos
)
115 int charpos
, bytepos
;
117 if (bytepos
< GPT_BYTE
)
118 gap_left (charpos
, bytepos
, 0);
119 else if (bytepos
> GPT_BYTE
)
120 gap_right (charpos
, bytepos
);
123 /* Move the gap to a position less than the current GPT.
124 BYTEPOS describes the new position as a byte position,
125 and CHARPOS is the corresponding char position.
126 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
129 gap_left (charpos
, bytepos
, newgap
)
130 register int charpos
, bytepos
;
133 register unsigned char *to
, *from
;
139 if (unchanged_modified
== MODIFF
140 && overlay_unchanged_modified
== OVERLAY_MODIFF
)
142 beg_unchanged
= charpos
- BEG
;
143 end_unchanged
= Z
- charpos
;
147 if (Z
- GPT
< end_unchanged
)
148 end_unchanged
= Z
- GPT
;
149 if (charpos
< beg_unchanged
)
150 beg_unchanged
= charpos
- BEG
;
159 /* Now copy the characters. To move the gap down,
160 copy characters up. */
164 /* I gets number of characters left to copy. */
165 i
= new_s1
- bytepos
;
168 /* If a quit is requested, stop copying now.
169 Change BYTEPOS to be where we have actually moved the gap to. */
173 charpos
= BYTE_TO_CHAR (bytepos
);
176 /* Move at most 32000 chars before checking again for a quit. */
181 /* bcopy is safe if the two areas of memory do not overlap
182 or on systems where bcopy is always safe for moving upward. */
183 && (BCOPY_UPWARD_SAFE
184 || to
- from
>= 128))
186 /* If overlap is not safe, avoid it by not moving too many
187 characters at once. */
188 if (!BCOPY_UPWARD_SAFE
&& i
> to
- from
)
203 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
204 BYTEPOS is where the loop above stopped, which may be what was specified
205 or may be where a quit was detected. */
206 adjust_markers_gap_motion (bytepos
, GPT_BYTE
, GAP_SIZE
);
209 if (bytepos
< charpos
)
211 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
215 /* Move the gap to a position greater than than the current GPT.
216 BYTEPOS describes the new position as a byte position,
217 and CHARPOS is the corresponding char position. */
220 gap_right (charpos
, bytepos
)
221 register int charpos
, bytepos
;
223 register unsigned char *to
, *from
;
227 if (unchanged_modified
== MODIFF
228 && overlay_unchanged_modified
== OVERLAY_MODIFF
)
230 beg_unchanged
= charpos
- BEG
;
231 end_unchanged
= Z
- charpos
;
235 if (Z
- charpos
- 1 < end_unchanged
)
236 end_unchanged
= Z
- charpos
;
237 if (GPT
- BEG
< beg_unchanged
)
238 beg_unchanged
= GPT
- BEG
;
246 /* Now copy the characters. To move the gap up,
247 copy characters down. */
251 /* I gets number of characters left to copy. */
252 i
= bytepos
- new_s1
;
255 /* If a quit is requested, stop copying now.
256 Change BYTEPOS to be where we have actually moved the gap to. */
260 charpos
= BYTE_TO_CHAR (bytepos
);
263 /* Move at most 32000 chars before checking again for a quit. */
268 /* bcopy is safe if the two areas of memory do not overlap
269 or on systems where bcopy is always safe for moving downward. */
270 && (BCOPY_DOWNWARD_SAFE
271 || from
- to
>= 128))
273 /* If overlap is not safe, avoid it by not moving too many
274 characters at once. */
275 if (!BCOPY_DOWNWARD_SAFE
&& i
> from
- to
)
290 adjust_markers_gap_motion (GPT_BYTE
+ GAP_SIZE
, bytepos
+ GAP_SIZE
,
294 if (bytepos
< charpos
)
296 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
300 /* Add AMOUNT to the byte position of every marker in the current buffer
301 whose current byte position is between FROM (exclusive) and TO (inclusive).
303 Also, any markers past the outside of that interval, in the direction
304 of adjustment, are first moved back to the near end of the interval
305 and then adjusted by AMOUNT.
307 When the latter adjustment is done, if AMOUNT is negative,
308 we record the adjustment for undo. (This case happens only for
311 The markers' character positions are not altered,
312 because gap motion does not affect character positions. */
314 int adjust_markers_test
;
317 adjust_markers_gap_motion (from
, to
, amount
)
318 register int from
, to
, amount
;
320 /* Now that a marker has a bytepos, not counting the gap,
321 nothing needs to be done here. */
324 register struct Lisp_Marker
*m
;
327 marker
= BUF_MARKERS (current_buffer
);
329 while (!NILP (marker
))
331 m
= XMARKER (marker
);
335 if (mpos
> to
&& mpos
< to
+ amount
)
337 if (adjust_markers_test
)
344 /* Here's the case where a marker is inside text being deleted.
345 AMOUNT can be negative for gap motion, too,
346 but then this range contains no markers. */
347 if (mpos
> from
+ amount
&& mpos
<= from
)
349 if (adjust_markers_test
)
351 mpos
= from
+ amount
;
354 if (mpos
> from
&& mpos
<= to
)
362 /* Adjust all markers for a deletion
363 whose range in bytes is FROM_BYTE to TO_BYTE.
364 The range in charpos is FROM to TO.
366 This function assumes that the gap is adjacent to
367 or inside of the range being deleted. */
370 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
)
371 register int from
, from_byte
, to
, to_byte
;
374 register struct Lisp_Marker
*m
;
375 register int charpos
;
377 marker
= BUF_MARKERS (current_buffer
);
379 while (!NILP (marker
))
381 m
= XMARKER (marker
);
382 charpos
= m
->charpos
;
387 /* If the marker is after the deletion,
388 relocate by number of chars / bytes deleted. */
391 m
->charpos
-= to
- from
;
392 m
->bytepos
-= to_byte
- from_byte
;
395 /* Here's the case where a marker is inside text being deleted. */
396 else if (charpos
> from
)
398 record_marker_adjustment (marker
, from
- charpos
);
400 m
->bytepos
= from_byte
;
408 /* Adjust all markers for calling record_delete for combining bytes.
409 whose range in bytes is FROM_BYTE to TO_BYTE.
410 The range in charpos is FROM to TO. */
413 adjust_markers_for_record_delete (from
, from_byte
, to
, to_byte
)
414 register int from
, from_byte
, to
, to_byte
;
417 register struct Lisp_Marker
*m
;
418 register int charpos
;
420 marker
= BUF_MARKERS (current_buffer
);
422 while (!NILP (marker
))
424 m
= XMARKER (marker
);
425 charpos
= m
->charpos
;
427 /* If the marker is after the deletion,
428 relocate by number of chars / bytes deleted. */
431 /* Here's the case where a marker is inside text being deleted. */
432 else if (charpos
> from
)
433 record_marker_adjustment (marker
, from
- charpos
);
439 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
440 to TO / TO_BYTE. We have to relocate the charpos of every marker
441 that points after the insertion (but not their bytepos).
443 COMBINED_BEFORE_BYTES is the number of bytes at the start of the insertion
444 that combine into one character with the text before the insertion.
445 COMBINED_AFTER_BYTES is the number of bytes after the insertion
446 that combine into one character with the last inserted bytes.
448 When a marker points at the insertion point,
449 we advance it if either its insertion-type is t
450 or BEFORE_MARKERS is true. */
453 adjust_markers_for_insert (from
, from_byte
, to
, to_byte
,
454 combined_before_bytes
, combined_after_bytes
,
456 register int from
, from_byte
, to
, to_byte
;
457 int combined_before_bytes
, combined_after_bytes
, before_markers
;
461 int nchars
= to
- from
;
462 int nbytes
= to_byte
- from_byte
;
464 marker
= BUF_MARKERS (current_buffer
);
466 while (!NILP (marker
))
468 register struct Lisp_Marker
*m
= XMARKER (marker
);
470 /* In a single-byte buffer, a marker's two positions must be equal.
471 (If this insertion is going to combine characters, Z will
472 become different from Z_BYTE, but they might be the same now.
473 If so, the two OLD positions of the marker should be equal.) */
476 if (m
->charpos
!= m
->bytepos
)
480 if (m
->bytepos
== from_byte
)
482 if (m
->insertion_type
|| before_markers
)
484 m
->bytepos
= to_byte
+ combined_after_bytes
;
485 m
->charpos
= to
- combined_before_bytes
;
486 /* Point the marker before the combined character,
487 so that undoing the insertion puts it back where it was. */
488 if (combined_after_bytes
)
489 DEC_BOTH (m
->charpos
, m
->bytepos
);
490 if (m
->insertion_type
)
493 else if (combined_before_bytes
)
495 /* This marker doesn't "need relocation",
496 but don't leave it pointing in the middle of a character.
497 Point the marker after the combined character,
498 so that undoing the insertion puts it back where it was. */
499 m
->bytepos
+= combined_before_bytes
;
500 if (combined_before_bytes
== nbytes
)
501 /* All new bytes plus combined_after_bytes (if any)
503 m
->bytepos
+= combined_after_bytes
;
506 /* If a marker was pointing into the combining bytes
507 after the insertion, don't leave it there
508 in the middle of a character. */
509 else if (combined_after_bytes
&& m
->bytepos
>= from_byte
510 && m
->bytepos
< from_byte
+ combined_after_bytes
)
512 /* Put it after the combining bytes. */
513 m
->bytepos
= to_byte
+ combined_after_bytes
;
514 m
->charpos
= to
- combined_before_bytes
;
515 /* Now move it back before the combined character,
516 so that undoing the insertion will put it where it was. */
517 DEC_BOTH (m
->charpos
, m
->bytepos
);
519 else if (m
->bytepos
> from_byte
)
521 m
->bytepos
+= nbytes
;
522 m
->charpos
+= nchars
- combined_after_bytes
- combined_before_bytes
;
528 /* Adjusting only markers whose insertion-type is t may result in
529 disordered overlays in the slot `overlays_before'. */
531 fix_overlays_before (current_buffer
, from
, to
);
534 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
536 This is used only when the value of point changes due to an insert
537 or delete; it does not represent a conceptual change in point as a
538 marker. In particular, point is not crossing any interval
539 boundaries, so there's no need to use the usual SET_PT macro. In
540 fact it would be incorrect to do so, because either the old or the
541 new value of point is out of sync with the current set of
545 adjust_point (nchars
, nbytes
)
548 BUF_PT (current_buffer
) += nchars
;
549 BUF_PT_BYTE (current_buffer
) += nbytes
;
551 /* In a single-byte buffer, the two positions must be equal. */
557 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
558 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
561 See the comment of adjust_markers_for_insert for the args
562 COMBINED_BEFORE_BYTES and COMBINED_AFTER_BYTES. */
565 adjust_markers_for_replace (from
, from_byte
, old_chars
, old_bytes
,
566 new_chars
, new_bytes
,
567 combined_before_bytes
, combined_after_bytes
)
568 int from
, from_byte
, old_chars
, old_bytes
, new_chars
, new_bytes
;
569 int combined_before_bytes
, combined_after_bytes
;
571 Lisp_Object marker
= BUF_MARKERS (current_buffer
);
572 int prev_to_byte
= from_byte
+ old_bytes
;
574 = (new_chars
- combined_before_bytes
) - (old_chars
+ combined_after_bytes
);
575 int diff_bytes
= new_bytes
- old_bytes
;
577 while (!NILP (marker
))
579 register struct Lisp_Marker
*m
= XMARKER (marker
);
581 if (m
->bytepos
>= prev_to_byte
)
583 if (m
->bytepos
< prev_to_byte
+ combined_after_bytes
)
585 /* Put it after the combining bytes. */
586 m
->bytepos
= from_byte
+ new_bytes
+ combined_after_bytes
;
587 m
->charpos
= from
+ new_chars
- combined_before_bytes
;
591 m
->charpos
+= diff_chars
;
592 m
->bytepos
+= diff_bytes
;
595 else if (m
->bytepos
>= from_byte
)
598 m
->bytepos
= from_byte
+ combined_before_bytes
;
599 /* If all new bytes are combined in addition to that there
600 are after combining bytes, we must set byte position of
601 the marker after the after combining bytes. */
602 if (combined_before_bytes
== new_bytes
)
603 m
->bytepos
+= combined_after_bytes
;
613 /* Make the gap NBYTES_ADDED bytes longer. */
616 make_gap (nbytes_added
)
619 unsigned char *result
;
622 int real_gap_loc_byte
;
625 /* If we have to get more space, get enough to last a while. */
626 nbytes_added
+= 2000;
628 /* Don't allow a buffer size that won't fit in an int
629 even if it will fit in a Lisp integer.
630 That won't work because so many places use `int'. */
632 if (Z_BYTE
- BEG_BYTE
+ GAP_SIZE
+ nbytes_added
633 >= ((unsigned) 1 << (min (BITS_PER_INT
, VALBITS
) - 1)))
634 error ("Buffer exceeds maximum size");
637 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */
638 result
= BUFFER_REALLOC (BEG_ADDR
, (Z_BYTE
- BEG_BYTE
639 + GAP_SIZE
+ nbytes_added
+ 1));
647 /* We can't unblock until the new address is properly stored. */
651 /* Prevent quitting in move_gap. */
656 real_gap_loc_byte
= GPT_BYTE
;
657 old_gap_size
= GAP_SIZE
;
659 /* Call the newly allocated space a gap at the end of the whole space. */
661 GPT_BYTE
= Z_BYTE
+ GAP_SIZE
;
662 GAP_SIZE
= nbytes_added
;
664 /* Move the new gap down to be consecutive with the end of the old one.
665 This adjusts the markers properly too. */
666 gap_left (real_gap_loc
+ old_gap_size
, real_gap_loc_byte
+ old_gap_size
, 1);
668 /* Now combine the two into one large gap. */
669 GAP_SIZE
+= old_gap_size
;
671 GPT_BYTE
= real_gap_loc_byte
;
679 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
680 FROM_MULTIBYTE says whether the incoming text is multibyte.
681 TO_MULTIBYTE says whether to store the text as multibyte.
682 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
684 Return the number of bytes stored at TO_ADDR. */
687 copy_text (from_addr
, to_addr
, nbytes
,
688 from_multibyte
, to_multibyte
)
689 unsigned char *from_addr
;
690 unsigned char *to_addr
;
692 int from_multibyte
, to_multibyte
;
694 if (from_multibyte
== to_multibyte
)
696 bcopy (from_addr
, to_addr
, nbytes
);
699 else if (from_multibyte
)
702 int bytes_left
= nbytes
;
703 Lisp_Object tbl
= Qnil
, temp
;
705 /* We set the variable tbl to the reverse table of
706 Vnonascii_translation_table in advance. */
707 if (CHAR_TABLE_P (Vnonascii_translation_table
))
709 tbl
= Fchar_table_extra_slot (Vnonascii_translation_table
,
711 if (!CHAR_TABLE_P (tbl
))
715 /* Convert multibyte to single byte. */
716 while (bytes_left
> 0)
718 int thislen
, c
, c_save
;
719 c
= c_save
= STRING_CHAR_AND_LENGTH (from_addr
, bytes_left
, thislen
);
720 if (!SINGLE_BYTE_CHAR_P (c
))
721 c
= multibyte_char_to_unibyte (c
, tbl
);
723 from_addr
+= thislen
;
724 bytes_left
-= thislen
;
731 unsigned char *initial_to_addr
= to_addr
;
733 /* Convert single-byte to multibyte. */
736 int c
= *from_addr
++;
737 unsigned char workbuf
[4], *str
;
740 if ((c
>= 0240 || !NILP (Vnonascii_translation_table
)) && c
< 0400)
742 c
= unibyte_char_to_multibyte (c
);
743 len
= CHAR_STRING (c
, workbuf
, str
);
744 bcopy (str
, to_addr
, len
);
749 /* Special case for speed. */
750 *to_addr
++ = c
, nbytes
--;
752 return to_addr
- initial_to_addr
;
756 /* Return the number of bytes it would take
757 to convert some single-byte text to multibyte.
758 The single-byte text consists of NBYTES bytes at PTR. */
761 count_size_as_multibyte (ptr
, nbytes
)
766 int outgoing_nbytes
= 0;
768 for (i
= 0; i
< nbytes
; i
++)
770 unsigned int c
= *ptr
++;
772 if (c
< 0240 && NILP (Vnonascii_translation_table
))
776 c
= unibyte_char_to_multibyte (c
);
777 outgoing_nbytes
+= CHAR_BYTES (c
);
781 return outgoing_nbytes
;
784 /* Insert a string of specified length before point.
785 This function judges multibyteness based on
786 enable_multibyte_characters in the current buffer;
787 it never converts between single-byte and multibyte.
789 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
790 prepare_to_modify_buffer could relocate the text. */
793 insert (string
, nbytes
)
794 register unsigned char *string
;
800 insert_1 (string
, nbytes
, 0, 1, 0);
801 signal_after_change (opoint
, 0, PT
- opoint
);
805 /* Likewise, but inherit text properties from neighboring characters. */
808 insert_and_inherit (string
, nbytes
)
809 register unsigned char *string
;
815 insert_1 (string
, nbytes
, 1, 1, 0);
816 signal_after_change (opoint
, 0, PT
- opoint
);
820 /* Insert the character C before point. Do not inherit text properties. */
826 unsigned char workbuf
[4], *str
;
829 if (! NILP (current_buffer
->enable_multibyte_characters
))
830 len
= CHAR_STRING (c
, workbuf
, str
);
841 /* Insert the null-terminated string S before point. */
847 insert (s
, strlen (s
));
850 /* Like `insert' except that all markers pointing at the place where
851 the insertion happens are adjusted to point after it.
852 Don't use this function to insert part of a Lisp string,
853 since gc could happen and relocate it. */
856 insert_before_markers (string
, nbytes
)
857 unsigned char *string
;
864 insert_1 (string
, nbytes
, 0, 1, 1);
865 signal_after_change (opoint
, 0, PT
- opoint
);
869 /* Likewise, but inherit text properties from neighboring characters. */
872 insert_before_markers_and_inherit (string
, nbytes
)
873 unsigned char *string
;
880 insert_1 (string
, nbytes
, 1, 1, 1);
881 signal_after_change (opoint
, 0, PT
- opoint
);
885 /* Subroutine used by the insert functions above. */
888 insert_1 (string
, nbytes
, inherit
, prepare
, before_markers
)
889 register unsigned char *string
;
891 int inherit
, prepare
, before_markers
;
893 insert_1_both (string
, chars_in_text (string
, nbytes
), nbytes
,
894 inherit
, prepare
, before_markers
);
897 /* See if the bytes before POS/POS_BYTE combine with bytes
898 at the start of STRING to form a single character.
899 If so, return the number of bytes at the start of STRING
900 which combine in this way. Otherwise, return 0. */
903 count_combining_before (string
, length
, pos
, pos_byte
)
904 unsigned char *string
;
908 int opos
= pos
, opos_byte
= pos_byte
;
910 unsigned char *p
= string
;
912 if (NILP (current_buffer
->enable_multibyte_characters
))
914 if (length
== 0 || CHAR_HEAD_P (*string
))
918 c
= FETCH_BYTE (pos_byte
- 1);
919 if (ASCII_BYTE_P (c
))
921 DEC_BOTH (pos
, pos_byte
);
922 c
= FETCH_BYTE (pos_byte
);
923 if (! BASE_LEADING_CODE_P (c
))
926 /* We have a combination situation.
927 Count the bytes at STRING that will combine. */
928 while (!CHAR_HEAD_P (*p
) && p
< string
+ length
)
934 /* See if the bytes after POS/POS_BYTE combine with bytes
935 at the end of STRING to form a single character.
936 If so, return the number of bytes after POS/POS_BYTE
937 which combine in this way. Otherwise, return 0. */
940 count_combining_after (string
, length
, pos
, pos_byte
)
941 unsigned char *string
;
945 int opos
= pos
, opos_byte
= pos_byte
;
949 if (NILP (current_buffer
->enable_multibyte_characters
))
951 if (length
> 0 && ASCII_BYTE_P (string
[length
- 1]))
954 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
960 /* All characters in `string' are not character head.
961 We must check also preceding bytes at POS.
962 We are sure that the gap is at POS. */
965 while (i
>= 0 && ! CHAR_HEAD_P (string
[i
]))
967 if (i
< 0 || !BASE_LEADING_CODE_P (string
[i
]))
970 else if (!BASE_LEADING_CODE_P (string
[i
]))
975 c
= FETCH_BYTE (pos_byte
);
978 while (pos_byte
< Z_BYTE
)
980 c
= FETCH_BYTE (pos_byte
);
986 return pos_byte
- opos_byte
;
989 /* Adjust the position TARGET/TARGET_BYTE for the combining of NBYTES
990 following the position POS/POS_BYTE to the character preceding POS.
991 If TARGET is after POS+NBYTES, we only have to adjust the character
992 position TARGET, else, if TARGET is after POS, we have to adjust
993 both the character position TARGET and the byte position
994 TARGET_BYTE, else we don't have to do any adjustment. */
996 #define ADJUST_CHAR_POS(target, target_byte) \
998 if (target > pos + nbytes) \
1000 else if (target >= pos) \
1003 target_byte = pos_byte + nbytes; \
1007 /* Combine NBYTES stray trailing-codes, which were formerly separate
1008 characters, with the preceding character. These bytes
1009 are located after position POS / POS_BYTE, and the preceding character
1010 is located just before that position.
1012 This function does not adjust markers for byte combining. That
1013 should be done in advance by the functions
1014 adjust_markers_for_insert or adjust_markers_for_replace. */
1017 combine_bytes (pos
, pos_byte
, nbytes
)
1018 int pos
, pos_byte
, nbytes
;
1020 adjust_overlays_for_delete (pos
, nbytes
);
1022 ADJUST_CHAR_POS (BUF_PT (current_buffer
), BUF_PT_BYTE (current_buffer
));
1023 ADJUST_CHAR_POS (GPT
, GPT_BYTE
);
1024 ADJUST_CHAR_POS (Z
, Z_BYTE
);
1025 ADJUST_CHAR_POS (ZV
, ZV_BYTE
);
1027 if (BUF_INTERVALS (current_buffer
) != 0)
1028 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
1029 offset_intervals (current_buffer
, pos
, - nbytes
);
1033 byte_combining_error ()
1035 error ("Byte combining across region boundary 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 register Lisp_Object temp
;
1059 int combined_before_bytes
, combined_after_bytes
;
1061 if (NILP (current_buffer
->enable_multibyte_characters
))
1065 /* Do this before moving and increasing the gap,
1066 because the before-change hooks might move the gap
1067 or make it smaller. */
1068 prepare_to_modify_buffer (PT
, PT
, NULL
);
1071 move_gap_both (PT
, PT_BYTE
);
1072 if (GAP_SIZE
< nbytes
)
1073 make_gap (nbytes
- GAP_SIZE
);
1075 combined_before_bytes
1076 = count_combining_before (string
, nbytes
, PT
, PT_BYTE
);
1077 combined_after_bytes
1078 = count_combining_after (string
, nbytes
, PT
, PT_BYTE
);
1079 CHECK_BYTE_COMBINING_FOR_INSERT (PT
);
1081 /* Record deletion of the surrounding text that combines with
1082 the insertion. This, together with recording the insertion,
1083 will add up to the right stuff in the undo list.
1085 But there is no need to actually delete the combining bytes
1086 from the buffer and reinsert them. */
1088 if (combined_after_bytes
)
1090 Lisp_Object deletion
;
1093 if (! EQ (current_buffer
->undo_list
, Qt
))
1094 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1095 PT
+ combined_after_bytes
,
1096 PT_BYTE
+ combined_after_bytes
, 1);
1098 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1099 PT
+ combined_after_bytes
,
1100 PT_BYTE
+ combined_after_bytes
);
1101 if (! EQ (current_buffer
->undo_list
, Qt
))
1102 record_delete (PT
, deletion
);
1105 if (combined_before_bytes
)
1107 Lisp_Object deletion
;
1110 if (! EQ (current_buffer
->undo_list
, Qt
))
1111 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1113 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1115 if (! EQ (current_buffer
->undo_list
, Qt
))
1116 record_delete (PT
- 1, deletion
);
1119 record_insert (PT
- !!combined_before_bytes
,
1120 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1123 bcopy (string
, GPT_ADDR
, nbytes
);
1126 /* When we have combining at the end of the insertion,
1127 this is the character position before the combined character. */
1134 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1136 if (combined_after_bytes
)
1137 move_gap_both (GPT
+ combined_after_bytes
,
1138 GPT_BYTE
+ combined_after_bytes
);
1143 adjust_overlays_for_insert (PT
, nchars
);
1144 adjust_markers_for_insert (PT
, PT_BYTE
,
1145 PT
+ nchars
, PT_BYTE
+ nbytes
,
1146 combined_before_bytes
, combined_after_bytes
,
1149 #ifdef USE_TEXT_PROPERTIES
1150 if (BUF_INTERVALS (current_buffer
) != 0)
1151 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
1152 offset_intervals (current_buffer
, PT
, nchars
);
1154 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
1155 Fset_text_properties (make_number (PT
), make_number (PT
+ nchars
),
1160 int pos
= PT
, pos_byte
= PT_BYTE
;
1162 adjust_point (nchars
+ combined_after_bytes
,
1163 nbytes
+ combined_after_bytes
);
1165 if (combined_after_bytes
)
1166 combine_bytes (pos
+ nchars
, pos_byte
+ nbytes
, combined_after_bytes
);
1168 if (combined_before_bytes
)
1169 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1175 /* Insert the part of the text of STRING, a Lisp object assumed to be
1176 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1177 starting at position POS / POS_BYTE. If the text of STRING has properties,
1178 copy them into the buffer.
1180 It does not work to use `insert' for this, because a GC could happen
1181 before we bcopy the stuff into the buffer, and relocate the string
1182 without insert noticing. */
1185 insert_from_string (string
, pos
, pos_byte
, length
, length_byte
, inherit
)
1187 register int pos
, pos_byte
, length
, length_byte
;
1191 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1193 signal_after_change (opoint
, 0, PT
- opoint
);
1196 /* Like `insert_from_string' except that all markers pointing
1197 at the place where the insertion happens are adjusted to point after it. */
1200 insert_from_string_before_markers (string
, pos
, pos_byte
,
1201 length
, length_byte
, inherit
)
1203 register int pos
, pos_byte
, length
, length_byte
;
1207 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1209 signal_after_change (opoint
, 0, PT
- opoint
);
1212 /* Subroutine of the insertion functions above. */
1215 insert_from_string_1 (string
, pos
, pos_byte
, nchars
, nbytes
,
1216 inherit
, before_markers
)
1218 register int pos
, pos_byte
, nchars
, nbytes
;
1219 int inherit
, before_markers
;
1221 register Lisp_Object temp
;
1222 struct gcpro gcpro1
;
1223 int outgoing_nbytes
= nbytes
;
1224 int combined_before_bytes
, combined_after_bytes
;
1225 int adjusted_nchars
;
1228 /* Make OUTGOING_NBYTES describe the text
1229 as it will be inserted in this buffer. */
1231 if (NILP (current_buffer
->enable_multibyte_characters
))
1232 outgoing_nbytes
= nchars
;
1233 else if (! STRING_MULTIBYTE (string
))
1235 = count_size_as_multibyte (&XSTRING (string
)->data
[pos_byte
],
1239 /* Do this before moving and increasing the gap,
1240 because the before-change hooks might move the gap
1241 or make it smaller. */
1242 prepare_to_modify_buffer (PT
, PT
, NULL
);
1245 move_gap_both (PT
, PT_BYTE
);
1246 if (GAP_SIZE
< nbytes
)
1247 make_gap (outgoing_nbytes
- GAP_SIZE
);
1250 /* Copy the string text into the buffer, perhaps converting
1251 between single-byte and multibyte. */
1252 copy_text (XSTRING (string
)->data
+ pos_byte
, GPT_ADDR
, nbytes
,
1253 STRING_MULTIBYTE (string
),
1254 ! NILP (current_buffer
->enable_multibyte_characters
));
1256 /* We have copied text into the gap, but we have not altered
1257 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1258 to these functions and get the same results as we would
1259 have got earlier on. Meanwhile, PT_ADDR does point to
1260 the text that has been stored by copy_text. */
1262 combined_before_bytes
1263 = count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1264 combined_after_bytes
1265 = count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1267 unsigned char save
= *(GPT_ADDR
);
1269 CHECK_BYTE_COMBINING_FOR_INSERT (PT
);
1273 /* Record deletion of the surrounding text that combines with
1274 the insertion. This, together with recording the insertion,
1275 will add up to the right stuff in the undo list.
1277 But there is no need to actually delete the combining bytes
1278 from the buffer and reinsert them. */
1280 if (combined_after_bytes
)
1282 Lisp_Object deletion
;
1285 if (! EQ (current_buffer
->undo_list
, Qt
))
1286 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1287 PT
+ combined_after_bytes
,
1288 PT_BYTE
+ combined_after_bytes
, 1);
1290 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1291 PT
+ combined_after_bytes
,
1292 PT_BYTE
+ combined_after_bytes
);
1293 if (! EQ (current_buffer
->undo_list
, Qt
))
1294 record_delete (PT
, deletion
);
1297 if (combined_before_bytes
)
1299 Lisp_Object deletion
;
1302 if (! EQ (current_buffer
->undo_list
, Qt
))
1303 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1305 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1307 if (! EQ (current_buffer
->undo_list
, Qt
))
1308 record_delete (PT
- 1, deletion
);
1311 record_insert (PT
- !!combined_before_bytes
,
1312 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1315 GAP_SIZE
-= outgoing_nbytes
;
1319 GPT_BYTE
+= outgoing_nbytes
;
1320 ZV_BYTE
+= outgoing_nbytes
;
1321 Z_BYTE
+= outgoing_nbytes
;
1322 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1324 if (combined_after_bytes
)
1325 move_gap_both (GPT
+ combined_after_bytes
,
1326 GPT_BYTE
+ combined_after_bytes
);
1331 adjust_overlays_for_insert (PT
, nchars
);
1332 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1333 PT_BYTE
+ outgoing_nbytes
,
1334 combined_before_bytes
, combined_after_bytes
,
1337 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1338 offset_intervals (current_buffer
, PT
, nchars
);
1340 intervals
= XSTRING (string
)->intervals
;
1341 /* Get the intervals for the part of the string we are inserting--
1342 not including the combined-before bytes. */
1343 if (nbytes
< STRING_BYTES (XSTRING (string
)))
1344 intervals
= copy_intervals (intervals
, pos
, nchars
);
1346 /* Insert those intervals. */
1347 graft_intervals_into_buffer (intervals
, PT
, nchars
,
1348 current_buffer
, inherit
);
1351 int pos
= PT
, pos_byte
= PT_BYTE
;
1353 adjust_point (nchars
+ combined_after_bytes
,
1354 outgoing_nbytes
+ combined_after_bytes
);
1356 if (combined_after_bytes
)
1357 combine_bytes (pos
+ nchars
, pos_byte
+ outgoing_nbytes
,
1358 combined_after_bytes
);
1360 if (combined_before_bytes
)
1361 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1365 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1366 current buffer. If the text in BUF has properties, they are absorbed
1367 into the current buffer.
1369 It does not work to use `insert' for this, because a malloc could happen
1370 and relocate BUF's text before the bcopy happens. */
1373 insert_from_buffer (buf
, charpos
, nchars
, inherit
)
1375 int charpos
, nchars
;
1380 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1381 signal_after_change (opoint
, 0, PT
- opoint
);
1385 insert_from_buffer_1 (buf
, from
, nchars
, inherit
)
1390 register Lisp_Object temp
;
1392 int from_byte
= buf_charpos_to_bytepos (buf
, from
);
1393 int to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1394 int incoming_nbytes
= to_byte
- from_byte
;
1395 int outgoing_nbytes
= incoming_nbytes
;
1396 int combined_before_bytes
, combined_after_bytes
;
1397 int adjusted_nchars
;
1400 /* Make OUTGOING_NBYTES describe the text
1401 as it will be inserted in this buffer. */
1403 if (NILP (current_buffer
->enable_multibyte_characters
))
1404 outgoing_nbytes
= nchars
;
1405 else if (NILP (buf
->enable_multibyte_characters
))
1407 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1410 /* Make sure point-max won't overflow after this insertion. */
1411 XSETINT (temp
, outgoing_nbytes
+ Z
);
1412 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1413 error ("Maximum buffer size exceeded");
1415 /* Do this before moving and increasing the gap,
1416 because the before-change hooks might move the gap
1417 or make it smaller. */
1418 prepare_to_modify_buffer (PT
, PT
, NULL
);
1421 move_gap_both (PT
, PT_BYTE
);
1422 if (GAP_SIZE
< outgoing_nbytes
)
1423 make_gap (outgoing_nbytes
- GAP_SIZE
);
1425 if (from
< BUF_GPT (buf
))
1427 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1428 if (chunk
> incoming_nbytes
)
1429 chunk
= incoming_nbytes
;
1430 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1432 ! NILP (buf
->enable_multibyte_characters
),
1433 ! NILP (current_buffer
->enable_multibyte_characters
));
1437 if (chunk
< incoming_nbytes
)
1438 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1439 GPT_ADDR
+ chunk
, incoming_nbytes
- chunk
,
1440 ! NILP (buf
->enable_multibyte_characters
),
1441 ! NILP (current_buffer
->enable_multibyte_characters
));
1443 /* We have copied text into the gap, but we have not altered
1444 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1445 to these functions and get the same results as we would
1446 have got earlier on. Meanwhile, GPT_ADDR does point to
1447 the text that has been stored by copy_text. */
1448 combined_before_bytes
1449 = count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1450 combined_after_bytes
1451 = count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1453 unsigned char save
= *(GPT_ADDR
);
1455 CHECK_BYTE_COMBINING_FOR_INSERT (PT
);
1459 /* Record deletion of the surrounding text that combines with
1460 the insertion. This, together with recording the insertion,
1461 will add up to the right stuff in the undo list.
1463 But there is no need to actually delete the combining bytes
1464 from the buffer and reinsert them. */
1466 if (combined_after_bytes
)
1468 Lisp_Object deletion
;
1471 if (! EQ (current_buffer
->undo_list
, Qt
))
1472 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1473 PT
+ combined_after_bytes
,
1474 PT_BYTE
+ combined_after_bytes
, 1);
1476 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1477 PT
+ combined_after_bytes
,
1478 PT_BYTE
+ combined_after_bytes
);
1479 if (! EQ (current_buffer
->undo_list
, Qt
))
1480 record_delete (PT
, deletion
);
1483 if (combined_before_bytes
)
1485 Lisp_Object deletion
;
1488 if (! EQ (current_buffer
->undo_list
, Qt
))
1489 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1491 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1493 if (! EQ (current_buffer
->undo_list
, Qt
))
1494 record_delete (PT
- 1, deletion
);
1497 record_insert (PT
- !!combined_before_bytes
,
1498 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1501 GAP_SIZE
-= outgoing_nbytes
;
1505 GPT_BYTE
+= outgoing_nbytes
;
1506 ZV_BYTE
+= outgoing_nbytes
;
1507 Z_BYTE
+= outgoing_nbytes
;
1508 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1510 if (combined_after_bytes
)
1511 move_gap_both (GPT
+ combined_after_bytes
,
1512 GPT_BYTE
+ combined_after_bytes
);
1517 adjust_overlays_for_insert (PT
, nchars
);
1518 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1519 PT_BYTE
+ outgoing_nbytes
,
1520 combined_before_bytes
, combined_after_bytes
, 0);
1522 #ifdef USE_TEXT_PROPERTIES
1523 if (BUF_INTERVALS (current_buffer
) != 0)
1524 offset_intervals (current_buffer
, PT
, nchars
);
1527 /* Get the intervals for the part of the string we are inserting--
1528 not including the combined-before bytes. */
1529 intervals
= BUF_INTERVALS (buf
);
1530 if (outgoing_nbytes
< BUF_Z_BYTE (buf
) - BUF_BEG_BYTE (buf
))
1531 intervals
= copy_intervals (intervals
, from
, nchars
);
1533 /* Insert those intervals. */
1534 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1537 int pos
= PT
, pos_byte
= PT_BYTE
;
1539 adjust_point (nchars
+ combined_after_bytes
,
1540 outgoing_nbytes
+ combined_after_bytes
);
1542 if (combined_after_bytes
)
1543 combine_bytes (pos
+ nchars
, pos_byte
+ outgoing_nbytes
,
1544 combined_after_bytes
);
1546 if (combined_before_bytes
)
1547 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1551 /* This function should be called after moving gap to FROM and before
1552 altering text between FROM and TO. This adjusts various position
1553 keepers and markers as if the text is deleted. Don't forget to
1554 call adjust_after_replace after you actually alter the text. */
1557 adjust_before_replace (from
, from_byte
, to
, to_byte
)
1558 int from
, from_byte
, to
, to_byte
;
1560 Lisp_Object deletion
;
1562 if (! EQ (current_buffer
->undo_list
, Qt
))
1563 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1567 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1569 if (! EQ (current_buffer
->undo_list
, Qt
))
1570 record_delete (from
, deletion
);
1572 adjust_overlays_for_delete (from
, to
- from
);
1575 /* Record undo information and adjust markers and position keepers for
1576 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1577 chars (LEN_BYTE bytes) which resides in the gap just after
1580 PREV_TEXT nil means the new text was just inserted. */
1583 adjust_after_replace (from
, from_byte
, prev_text
, len
, len_byte
)
1584 int from
, from_byte
, len
, len_byte
;
1585 Lisp_Object prev_text
;
1587 int combined_before_bytes
1588 = count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
);
1589 int combined_after_bytes
1590 = count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
);
1591 /* This flag tells if we combine some bytes with a character before
1592 FROM. This happens even if combined_before_bytes is zero. */
1593 int combine_before
= (combined_before_bytes
1594 || (len
== 0 && combined_after_bytes
));
1596 int nchars_del
= 0, nbytes_del
= 0;
1598 if (STRINGP (prev_text
))
1600 nchars_del
= XSTRING (prev_text
)->size
;
1601 nbytes_del
= STRING_BYTES (XSTRING (prev_text
));
1604 if (combine_before
&& from
== BEGV
1605 || combined_after_bytes
&& from
== ZV
)
1607 /* We can't combine bytes nor signal an error here. So, let's
1608 pretend that the new text is just a single space. */
1610 combined_before_bytes
= combined_after_bytes
= 0;
1614 if (combined_after_bytes
)
1616 Lisp_Object deletion
;
1619 if (! EQ (current_buffer
->undo_list
, Qt
))
1620 deletion
= make_buffer_string_both (from
, from_byte
,
1621 from
+ combined_after_bytes
,
1622 from_byte
+ combined_after_bytes
,
1625 adjust_markers_for_record_delete (from
, from_byte
,
1626 from
+ combined_after_bytes
,
1627 from_byte
+ combined_after_bytes
);
1629 if (! EQ (current_buffer
->undo_list
, Qt
))
1630 record_delete (from
+ nchars_del
, deletion
);
1633 if (combined_before_bytes
1634 || len_byte
== 0 && combined_after_bytes
> 0)
1636 Lisp_Object deletion
;
1639 if (! EQ (current_buffer
->undo_list
, Qt
))
1640 deletion
= make_buffer_string_both (from
- 1, CHAR_TO_BYTE (from
- 1),
1641 from
, from_byte
, 1);
1642 adjust_markers_for_record_delete (from
- 1, CHAR_TO_BYTE (from
- 1),
1644 if (! EQ (current_buffer
->undo_list
, Qt
))
1645 record_delete (from
- 1, deletion
);
1648 /* Update various buffer positions for the new text. */
1649 GAP_SIZE
-= len_byte
;
1651 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1652 GPT
+= len
; GPT_BYTE
+= len_byte
;
1653 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1655 /* The gap should be at character boundary. */
1656 if (combined_after_bytes
)
1657 move_gap_both (GPT
+ combined_after_bytes
,
1658 GPT_BYTE
+ combined_after_bytes
);
1660 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1662 combined_before_bytes
, combined_after_bytes
);
1663 if (! EQ (current_buffer
->undo_list
, Qt
))
1666 record_delete (from
- combine_before
, prev_text
);
1668 record_insert (from
- 1, len
- combined_before_bytes
+ 1);
1670 record_insert (from
, len
);
1673 if (len
> nchars_del
)
1674 adjust_overlays_for_insert (from
, len
- nchars_del
);
1675 else if (len
< nchars_del
)
1676 adjust_overlays_for_delete (from
, nchars_del
- len
);
1677 #ifdef USE_TEXT_PROPERTIES
1678 if (BUF_INTERVALS (current_buffer
) != 0)
1680 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1685 int pos
= PT
, pos_byte
= PT_BYTE
;
1688 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1690 if (combined_after_bytes
)
1692 if (combined_before_bytes
== len_byte
)
1693 /* This is the case that all new bytes are combined. */
1694 combined_before_bytes
+= combined_after_bytes
;
1696 combine_bytes (from
+ len
, from_byte
+ len_byte
,
1697 combined_after_bytes
);
1699 if (combined_before_bytes
)
1700 combine_bytes (from
, from_byte
, combined_before_bytes
);
1703 /* As byte combining will decrease Z, we must check this again. */
1704 if (Z
- GPT
< end_unchanged
)
1705 end_unchanged
= Z
- GPT
;
1710 evaporate_overlays (from
);
1714 /* Record undo information, adjust markers and position keepers for an
1715 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1716 text already exists in the current buffer but character length (TO
1717 - FROM) may be incorrect, the correct length is NEWLEN. */
1720 adjust_after_insert (from
, from_byte
, to
, to_byte
, newlen
)
1721 int from
, from_byte
, to
, to_byte
, newlen
;
1723 int len
= to
- from
, len_byte
= to_byte
- from_byte
;
1726 move_gap_both (to
, to_byte
);
1727 GAP_SIZE
+= len_byte
;
1728 GPT
-= len
; GPT_BYTE
-= len_byte
;
1729 ZV
-= len
; ZV_BYTE
-= len_byte
;
1730 Z
-= len
; Z_BYTE
-= len_byte
;
1731 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1734 /* Replace the text from character positions FROM to TO with NEW,
1735 If PREPARE is nonzero, call prepare_to_modify_buffer.
1736 If INHERIT, the newly inserted text should inherit text properties
1737 from the surrounding non-deleted text. */
1739 /* Note that this does not yet handle markers quite right.
1740 Also it needs to record a single undo-entry that does a replacement
1741 rather than a separate delete and insert.
1742 That way, undo will also handle markers properly.
1744 But if MARKERS is 0, don't relocate markers. */
1747 replace_range (from
, to
, new, prepare
, inherit
, markers
)
1749 int from
, to
, prepare
, inherit
, markers
;
1751 int inschars
= XSTRING (new)->size
;
1752 int insbytes
= STRING_BYTES (XSTRING (new));
1753 int from_byte
, to_byte
;
1754 int nbytes_del
, nchars_del
;
1755 register Lisp_Object temp
;
1756 struct gcpro gcpro1
;
1757 int combined_before_bytes
, combined_after_bytes
;
1758 int adjusted_inschars
;
1760 int outgoing_insbytes
= insbytes
;
1761 Lisp_Object deletion
;
1769 int range_length
= to
- from
;
1770 prepare_to_modify_buffer (from
, to
, &from
);
1771 to
= from
+ range_length
;
1776 /* Make args be valid */
1782 from_byte
= CHAR_TO_BYTE (from
);
1783 to_byte
= CHAR_TO_BYTE (to
);
1785 nchars_del
= to
- from
;
1786 nbytes_del
= to_byte
- from_byte
;
1788 if (nbytes_del
<= 0 && insbytes
== 0)
1791 /* Make OUTGOING_INSBYTES describe the text
1792 as it will be inserted in this buffer. */
1794 if (NILP (current_buffer
->enable_multibyte_characters
))
1795 outgoing_insbytes
= inschars
;
1796 else if (! STRING_MULTIBYTE (new))
1798 = count_size_as_multibyte (XSTRING (new)->data
, insbytes
);
1800 /* Make sure point-max won't overflow after this insertion. */
1801 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1802 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1803 error ("Maximum buffer size exceeded");
1807 /* Make sure the gap is somewhere in or next to what we are deleting. */
1809 gap_right (from
, from_byte
);
1811 gap_left (to
, to_byte
, 0);
1813 /* Even if we don't record for undo, we must keep the original text
1814 because we may have to recover it because of inappropriate byte
1816 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1819 /* Relocate all markers pointing into the new, larger gap
1820 to point at the end of the text before the gap.
1821 Do this before recording the deletion,
1822 so that undo handles this after reinserting the text. */
1823 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1825 GAP_SIZE
+= nbytes_del
;
1828 ZV_BYTE
-= nbytes_del
;
1829 Z_BYTE
-= nbytes_del
;
1831 GPT_BYTE
= from_byte
;
1832 *(GPT_ADDR
) = 0; /* Put an anchor. */
1837 if (GPT
- BEG
< beg_unchanged
)
1838 beg_unchanged
= GPT
- BEG
;
1839 if (Z
- GPT
< end_unchanged
)
1840 end_unchanged
= Z
- GPT
;
1842 if (GAP_SIZE
< insbytes
)
1843 make_gap (insbytes
- GAP_SIZE
);
1845 /* Copy the string text into the buffer, perhaps converting
1846 between single-byte and multibyte. */
1847 copy_text (XSTRING (new)->data
, GPT_ADDR
, insbytes
,
1848 STRING_MULTIBYTE (new),
1849 ! NILP (current_buffer
->enable_multibyte_characters
));
1851 /* We have copied text into the gap, but we have not marked
1852 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1853 here, for both the previous text and the following text.
1854 Meanwhile, GPT_ADDR does point to
1855 the text that has been stored by copy_text. */
1857 combined_before_bytes
1858 = count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
);
1859 combined_after_bytes
1860 = count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
);
1862 if (combined_before_bytes
&& from
== BEGV
1863 || combined_after_bytes
&& from
== ZV
)
1865 /* Bytes are being combined across the region boundary. We
1866 should avoid it. We recover the original contents before
1867 signaling an error. */
1868 bcopy (XSTRING (deletion
)->data
, GPT_ADDR
, nbytes_del
);
1869 GAP_SIZE
-= nbytes_del
;
1872 ZV_BYTE
+= nbytes_del
;
1873 Z_BYTE
+= nbytes_del
;
1874 GPT
= from
+ nchars_del
;
1875 GPT_BYTE
= from_byte
+ nbytes_del
;
1876 *(GPT_ADDR
) = 0; /* Put an anchor. */
1878 adjust_markers_for_insert (from
, from_byte
, to
, to_byte
, 0, 0, 0);
1880 byte_combining_error ();
1884 /* Record deletion of the surrounding text that combines with
1885 the insertion. This, together with recording the insertion,
1886 will add up to the right stuff in the undo list.
1888 But there is no need to actually delete the combining bytes
1889 from the buffer and reinsert them. */
1891 if (combined_after_bytes
)
1893 Lisp_Object deletion
;
1896 if (! EQ (current_buffer
->undo_list
, Qt
))
1897 deletion
= make_buffer_string_both (from
, from_byte
,
1898 from
+ combined_after_bytes
,
1899 from_byte
+ combined_after_bytes
,
1902 adjust_markers_for_record_delete (from
, from_byte
,
1903 from
+ combined_after_bytes
,
1904 from_byte
+ combined_after_bytes
);
1905 if (! EQ (current_buffer
->undo_list
, Qt
))
1906 record_delete (from
+ nchars_del
, deletion
);
1909 if (combined_before_bytes
)
1911 Lisp_Object deletion
;
1914 if (! EQ (current_buffer
->undo_list
, Qt
))
1915 deletion
= make_buffer_string_both (from
- 1, CHAR_TO_BYTE (from
- 1),
1916 from
, from_byte
, 1);
1917 adjust_markers_for_record_delete (from
- 1, CHAR_TO_BYTE (from
- 1),
1919 if (! EQ (current_buffer
->undo_list
, Qt
))
1920 record_delete (from
- 1, deletion
);
1923 if (! EQ (current_buffer
->undo_list
, Qt
))
1925 record_delete (from
- !!combined_before_bytes
, deletion
);
1926 record_insert (from
- !!combined_before_bytes
,
1927 (inschars
- combined_before_bytes
1928 + !!combined_before_bytes
));
1931 GAP_SIZE
-= outgoing_insbytes
;
1935 GPT_BYTE
+= outgoing_insbytes
;
1936 ZV_BYTE
+= outgoing_insbytes
;
1937 Z_BYTE
+= outgoing_insbytes
;
1938 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1940 if (combined_after_bytes
)
1941 move_gap_both (GPT
+ combined_after_bytes
,
1942 GPT_BYTE
+ combined_after_bytes
);
1947 /* Adjust the overlay center as needed. This must be done after
1948 adjusting the markers that bound the overlays. */
1949 adjust_overlays_for_delete (from
, nchars_del
);
1950 adjust_overlays_for_insert (from
, inschars
);
1952 adjust_markers_for_insert (from
, from_byte
,
1953 from
+ inschars
, from_byte
+ outgoing_insbytes
,
1954 combined_before_bytes
, combined_after_bytes
, 0);
1956 #ifdef USE_TEXT_PROPERTIES
1957 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1959 /* Get the intervals for the part of the string we are inserting--
1960 not including the combined-before bytes. */
1961 intervals
= XSTRING (new)->intervals
;
1962 /* Insert those intervals. */
1963 graft_intervals_into_buffer (intervals
, from
, inschars
,
1964 current_buffer
, inherit
);
1967 /* Relocate point as if it were a marker. */
1969 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1970 (from_byte
+ outgoing_insbytes
1971 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1973 if (combined_after_bytes
)
1975 if (combined_before_bytes
== outgoing_insbytes
)
1976 /* This is the case that all new bytes are combined. */
1977 combined_before_bytes
+= combined_after_bytes
;
1979 combine_bytes (from
+ inschars
, from_byte
+ outgoing_insbytes
,
1980 combined_after_bytes
);
1982 if (combined_before_bytes
)
1983 combine_bytes (from
, from_byte
, combined_before_bytes
);
1985 /* As byte combining will decrease Z, we must check this again. */
1986 if (Z
- GPT
< end_unchanged
)
1987 end_unchanged
= Z
- GPT
;
1989 if (outgoing_insbytes
== 0)
1990 evaporate_overlays (from
);
1997 signal_after_change (from
, nchars_del
, GPT
- from
);
2000 /* Delete characters in current buffer
2001 from FROM up to (but not including) TO.
2002 If TO comes before FROM, we delete nothing. */
2005 del_range (from
, to
)
2006 register int from
, to
;
2008 del_range_1 (from
, to
, 1);
2011 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
2014 del_range_1 (from
, to
, prepare
)
2015 int from
, to
, prepare
;
2017 int from_byte
, to_byte
;
2019 /* Make args be valid */
2030 int range_length
= to
- from
;
2031 prepare_to_modify_buffer (from
, to
, &from
);
2032 to
= from
+ range_length
;
2035 from_byte
= CHAR_TO_BYTE (from
);
2036 to_byte
= CHAR_TO_BYTE (to
);
2038 del_range_2 (from
, from_byte
, to
, to_byte
);
2041 /* Like del_range_1 but args are byte positions, not char positions. */
2044 del_range_byte (from_byte
, to_byte
, prepare
)
2045 int from_byte
, to_byte
, prepare
;
2049 /* Make args be valid */
2050 if (from_byte
< BEGV_BYTE
)
2051 from_byte
= BEGV_BYTE
;
2052 if (to_byte
> ZV_BYTE
)
2055 if (to_byte
<= from_byte
)
2058 from
= BYTE_TO_CHAR (from_byte
);
2059 to
= BYTE_TO_CHAR (to_byte
);
2063 int old_from
= from
, old_to
= Z
- to
;
2064 int range_length
= to
- from
;
2065 prepare_to_modify_buffer (from
, to
, &from
);
2066 to
= from
+ range_length
;
2068 if (old_from
!= from
)
2069 from_byte
= CHAR_TO_BYTE (from
);
2070 if (old_to
== Z
- to
)
2071 to_byte
= CHAR_TO_BYTE (to
);
2074 del_range_2 (from
, from_byte
, to
, to_byte
);
2077 /* Like del_range_1, but positions are specified both as charpos
2081 del_range_both (from
, from_byte
, to
, to_byte
, prepare
)
2082 int from
, from_byte
, to
, to_byte
, prepare
;
2084 /* Make args be valid */
2085 if (from_byte
< BEGV_BYTE
)
2086 from_byte
= BEGV_BYTE
;
2087 if (to_byte
> ZV_BYTE
)
2090 if (to_byte
<= from_byte
)
2100 int old_from
= from
, old_to
= Z
- to
;
2101 int range_length
= to
- from
;
2102 prepare_to_modify_buffer (from
, to
, &from
);
2103 to
= from
+ range_length
;
2105 if (old_from
!= from
)
2106 from_byte
= CHAR_TO_BYTE (from
);
2107 if (old_to
== Z
- to
)
2108 to_byte
= CHAR_TO_BYTE (to
);
2111 del_range_2 (from
, from_byte
, to
, to_byte
);
2114 /* Delete a range of text, specified both as character positions
2115 and byte positions. FROM and TO are character positions,
2116 while FROM_BYTE and TO_BYTE are byte positions. */
2119 del_range_2 (from
, from_byte
, to
, to_byte
)
2120 int from
, from_byte
, to
, to_byte
;
2122 register int nbytes_del
, nchars_del
;
2123 int combined_after_bytes
;
2124 Lisp_Object deletion
;
2129 nchars_del
= to
- from
;
2130 nbytes_del
= to_byte
- from_byte
;
2132 /* Make sure the gap is somewhere in or next to what we are deleting. */
2134 gap_right (from
, from_byte
);
2136 gap_left (to
, to_byte
, 0);
2138 combined_after_bytes
2139 = count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
2140 Z_BYTE
- to_byte
, from
, from_byte
);
2141 if (combined_after_bytes
)
2143 if (from
== BEGV
|| to
== ZV
)
2144 byte_combining_error ();
2145 from_byte_1
= from_byte
;
2146 DEC_POS (from_byte_1
);
2149 from_byte_1
= from_byte
;
2151 if (! EQ (current_buffer
->undo_list
, Qt
))
2153 = make_buffer_string_both (from
- !!combined_after_bytes
,
2155 to
+ combined_after_bytes
,
2156 to_byte
+ combined_after_bytes
, 1);
2157 if (combined_after_bytes
)
2158 /* COMBINED_AFTER_BYTES nonzero means that the above code moved
2159 the gap. We must move the gap again to a proper place. */
2160 move_gap_both (from
, from_byte
);
2162 /* Relocate all markers pointing into the new, larger gap
2163 to point at the end of the text before the gap.
2164 Do this before recording the deletion,
2165 so that undo handles this after reinserting the text. */
2166 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
2167 if (combined_after_bytes
)
2169 /* Adjust markers for the phony deletion
2170 that we are about to call record_undo for. */
2172 /* Here we delete the markers that formerly
2173 pointed at TO ... TO + COMBINED_AFTER_BYTES.
2174 But because of the call to adjust_markers_for_delete, above,
2175 they now point at FROM ... FROM + COMBINED_AFTER_BYTES. */
2176 adjust_markers_for_record_delete (from
, from_byte
,
2177 from
+ combined_after_bytes
,
2178 from_byte
+ combined_after_bytes
);
2180 adjust_markers_for_record_delete (from
- 1, from_byte_1
,
2183 if (! EQ (current_buffer
->undo_list
, Qt
))
2184 record_delete (from
- !!combined_after_bytes
, deletion
);
2187 /* Relocate point as if it were a marker. */
2189 adjust_point (from
- (PT
< to
? PT
: to
),
2190 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
2192 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
2193 offset_intervals (current_buffer
, from
, - nchars_del
);
2195 /* Adjust the overlay center as needed. This must be done after
2196 adjusting the markers that bound the overlays. */
2197 adjust_overlays_for_delete (from
, nchars_del
);
2199 GAP_SIZE
+= nbytes_del
;
2200 ZV_BYTE
-= nbytes_del
;
2201 Z_BYTE
-= nbytes_del
;
2205 GPT_BYTE
= from_byte
;
2207 if (combined_after_bytes
)
2208 move_gap_both (GPT
+ combined_after_bytes
,
2209 GPT_BYTE
+ combined_after_bytes
);
2211 *(GPT_ADDR
) = 0; /* Put an anchor. */
2216 if (GPT
- BEG
< beg_unchanged
)
2217 beg_unchanged
= GPT
- BEG
;
2218 if (Z
- GPT
< end_unchanged
)
2219 end_unchanged
= Z
- GPT
;
2221 if (combined_after_bytes
)
2223 /* Adjust markers for byte combining. As we have already
2224 adjuted markers without concerning byte combining, here we
2225 must concern only byte combining. */
2226 adjust_markers_for_replace (from
, from_byte
, 0, 0, 0, 0,
2227 0, combined_after_bytes
);
2228 combine_bytes (from
, from_byte
, combined_after_bytes
);
2230 record_insert (GPT
- 1, 1);
2232 if (Z
- GPT
< end_unchanged
)
2233 end_unchanged
= Z
- GPT
;
2238 evaporate_overlays (from
);
2239 signal_after_change (from
, nchars_del
, 0);
2242 /* Call this if you're about to change the region of BUFFER from
2243 character positions START to END. This checks the read-only
2244 properties of the region, calls the necessary modification hooks,
2245 and warns the next redisplay that it should pay attention to that
2249 modify_region (buffer
, start
, end
)
2250 struct buffer
*buffer
;
2253 struct buffer
*old_buffer
= current_buffer
;
2255 if (buffer
!= old_buffer
)
2256 set_buffer_internal (buffer
);
2258 prepare_to_modify_buffer (start
, end
, NULL
);
2260 if (start
- 1 < beg_unchanged
2261 || (unchanged_modified
== MODIFF
2262 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
2263 beg_unchanged
= start
- 1;
2264 if (Z
- end
< end_unchanged
2265 || (unchanged_modified
== MODIFF
2266 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
2267 end_unchanged
= Z
- end
;
2269 if (MODIFF
<= SAVE_MODIFF
)
2270 record_first_change ();
2273 buffer
->point_before_scroll
= Qnil
;
2275 if (buffer
!= old_buffer
)
2276 set_buffer_internal (old_buffer
);
2279 /* Check that it is okay to modify the buffer between START and END,
2280 which are char positions.
2282 Run the before-change-function, if any. If intervals are in use,
2283 verify that the text to be modified is not read-only, and call
2284 any modification properties the text may have.
2286 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2287 by holding its value temporarily in a marker. */
2290 prepare_to_modify_buffer (start
, end
, preserve_ptr
)
2294 if (!NILP (current_buffer
->read_only
))
2295 Fbarf_if_buffer_read_only ();
2297 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
2298 if (BUF_INTERVALS (current_buffer
) != 0)
2302 Lisp_Object preserve_marker
;
2303 struct gcpro gcpro1
;
2304 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
2305 GCPRO1 (preserve_marker
);
2306 verify_interval_modification (current_buffer
, start
, end
);
2307 *preserve_ptr
= marker_position (preserve_marker
);
2308 unchain_marker (preserve_marker
);
2312 verify_interval_modification (current_buffer
, start
, end
);
2315 #ifdef CLASH_DETECTION
2316 if (!NILP (current_buffer
->file_truename
)
2317 /* Make binding buffer-file-name to nil effective. */
2318 && !NILP (current_buffer
->filename
)
2319 && SAVE_MODIFF
>= MODIFF
)
2320 lock_file (current_buffer
->file_truename
);
2322 /* At least warn if this file has changed on disk since it was visited. */
2323 if (!NILP (current_buffer
->filename
)
2324 && SAVE_MODIFF
>= MODIFF
2325 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2326 && !NILP (Ffile_exists_p (current_buffer
->filename
)))
2327 call1 (intern ("ask-user-about-supersession-threat"),
2328 current_buffer
->filename
);
2329 #endif /* not CLASH_DETECTION */
2331 signal_before_change (start
, end
, preserve_ptr
);
2333 if (current_buffer
->newline_cache
)
2334 invalidate_region_cache (current_buffer
,
2335 current_buffer
->newline_cache
,
2336 start
- BEG
, Z
- end
);
2337 if (current_buffer
->width_run_cache
)
2338 invalidate_region_cache (current_buffer
,
2339 current_buffer
->width_run_cache
,
2340 start
- BEG
, Z
- end
);
2342 Vdeactivate_mark
= Qt
;
2345 /* These macros work with an argument named `preserve_ptr'
2346 and a local variable named `preserve_marker'. */
2348 #define PRESERVE_VALUE \
2349 if (preserve_ptr && NILP (preserve_marker)) \
2350 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2352 #define RESTORE_VALUE \
2353 if (! NILP (preserve_marker)) \
2355 *preserve_ptr = marker_position (preserve_marker); \
2356 unchain_marker (preserve_marker); \
2359 #define PRESERVE_START_END \
2360 if (NILP (start_marker)) \
2361 start_marker = Fcopy_marker (start, Qnil); \
2362 if (NILP (end_marker)) \
2363 end_marker = Fcopy_marker (end, Qnil);
2365 #define FETCH_START \
2366 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2369 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2371 /* Signal a change to the buffer immediately before it happens.
2372 START_INT and END_INT are the bounds of the text to be changed.
2374 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2375 by holding its value temporarily in a marker. */
2378 signal_before_change (start_int
, end_int
, preserve_ptr
)
2379 int start_int
, end_int
;
2382 Lisp_Object start
, end
;
2383 Lisp_Object start_marker
, end_marker
;
2384 Lisp_Object preserve_marker
;
2385 struct gcpro gcpro1
, gcpro2
, gcpro3
;
2387 if (inhibit_modification_hooks
)
2390 start
= make_number (start_int
);
2391 end
= make_number (end_int
);
2392 preserve_marker
= Qnil
;
2393 start_marker
= Qnil
;
2395 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
2397 /* If buffer is unmodified, run a special hook for that case. */
2398 if (SAVE_MODIFF
>= MODIFF
2399 && !NILP (Vfirst_change_hook
)
2400 && !NILP (Vrun_hooks
))
2404 call1 (Vrun_hooks
, Qfirst_change_hook
);
2407 /* Run the before-change-function if any.
2408 We don't bother "binding" this variable to nil
2409 because it is obsolete anyway and new code should not use it. */
2410 if (!NILP (Vbefore_change_function
))
2414 call2 (Vbefore_change_function
, FETCH_START
, FETCH_END
);
2417 /* Now run the before-change-functions if any. */
2418 if (!NILP (Vbefore_change_functions
))
2420 Lisp_Object args
[3];
2421 Lisp_Object before_change_functions
;
2422 Lisp_Object after_change_functions
;
2423 struct gcpro gcpro1
, gcpro2
;
2428 /* "Bind" before-change-functions and after-change-functions
2429 to nil--but in a way that errors don't know about.
2430 That way, if there's an error in them, they will stay nil. */
2431 before_change_functions
= Vbefore_change_functions
;
2432 after_change_functions
= Vafter_change_functions
;
2433 Vbefore_change_functions
= Qnil
;
2434 Vafter_change_functions
= Qnil
;
2435 GCPRO2 (before_change_functions
, after_change_functions
);
2437 /* Actually run the hook functions. */
2438 args
[0] = Qbefore_change_functions
;
2439 args
[1] = FETCH_START
;
2440 args
[2] = FETCH_END
;
2441 run_hook_list_with_args (before_change_functions
, 3, args
);
2443 /* "Unbind" the variables we "bound" to nil. */
2444 Vbefore_change_functions
= before_change_functions
;
2445 Vafter_change_functions
= after_change_functions
;
2449 if (!NILP (current_buffer
->overlays_before
)
2450 || !NILP (current_buffer
->overlays_after
))
2453 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2454 FETCH_START
, FETCH_END
, Qnil
);
2457 if (! NILP (start_marker
))
2458 free_marker (start_marker
);
2459 if (! NILP (end_marker
))
2460 free_marker (end_marker
);
2465 /* Signal a change immediately after it happens.
2466 CHARPOS is the character position of the start of the changed text.
2467 LENDEL is the number of characters of the text before the change.
2468 (Not the whole buffer; just the part that was changed.)
2469 LENINS is the number of characters in that part of the text
2470 after the change. */
2473 signal_after_change (charpos
, lendel
, lenins
)
2474 int charpos
, lendel
, lenins
;
2476 if (inhibit_modification_hooks
)
2479 /* If we are deferring calls to the after-change functions
2480 and there are no before-change functions,
2481 just record the args that we were going to use. */
2482 if (! NILP (Vcombine_after_change_calls
)
2483 && NILP (Vbefore_change_function
) && NILP (Vbefore_change_functions
)
2484 && NILP (current_buffer
->overlays_before
)
2485 && NILP (current_buffer
->overlays_after
))
2489 if (!NILP (combine_after_change_list
)
2490 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2491 Fcombine_after_change_execute ();
2493 elt
= Fcons (make_number (charpos
- BEG
),
2494 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2495 Fcons (make_number (lenins
- lendel
), Qnil
)));
2496 combine_after_change_list
2497 = Fcons (elt
, combine_after_change_list
);
2498 combine_after_change_buffer
= Fcurrent_buffer ();
2503 if (!NILP (combine_after_change_list
))
2504 Fcombine_after_change_execute ();
2506 /* Run the after-change-function if any.
2507 We don't bother "binding" this variable to nil
2508 because it is obsolete anyway and new code should not use it. */
2509 if (!NILP (Vafter_change_function
))
2510 call3 (Vafter_change_function
,
2511 make_number (charpos
), make_number (charpos
+ lenins
),
2512 make_number (lendel
));
2514 if (!NILP (Vafter_change_functions
))
2516 Lisp_Object args
[4];
2517 Lisp_Object before_change_functions
;
2518 Lisp_Object after_change_functions
;
2519 struct gcpro gcpro1
, gcpro2
;
2521 /* "Bind" before-change-functions and after-change-functions
2522 to nil--but in a way that errors don't know about.
2523 That way, if there's an error in them, they will stay nil. */
2524 before_change_functions
= Vbefore_change_functions
;
2525 after_change_functions
= Vafter_change_functions
;
2526 Vbefore_change_functions
= Qnil
;
2527 Vafter_change_functions
= Qnil
;
2528 GCPRO2 (before_change_functions
, after_change_functions
);
2530 /* Actually run the hook functions. */
2531 args
[0] = Qafter_change_functions
;
2532 XSETFASTINT (args
[1], charpos
);
2533 XSETFASTINT (args
[2], charpos
+ lenins
);
2534 XSETFASTINT (args
[3], lendel
);
2535 run_hook_list_with_args (after_change_functions
,
2538 /* "Unbind" the variables we "bound" to nil. */
2539 Vbefore_change_functions
= before_change_functions
;
2540 Vafter_change_functions
= after_change_functions
;
2544 if (!NILP (current_buffer
->overlays_before
)
2545 || !NILP (current_buffer
->overlays_after
))
2546 report_overlay_modification (make_number (charpos
),
2547 make_number (charpos
+ lenins
),
2549 make_number (charpos
),
2550 make_number (charpos
+ lenins
),
2551 make_number (lendel
));
2553 /* After an insertion, call the text properties
2554 insert-behind-hooks or insert-in-front-hooks. */
2556 report_interval_modification (make_number (charpos
),
2557 make_number (charpos
+ lenins
));
2561 Fcombine_after_change_execute_1 (val
)
2564 Vcombine_after_change_calls
= val
;
2568 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2569 Scombine_after_change_execute
, 0, 0, 0,
2570 "This function is for use internally in `combine-after-change-calls'.")
2573 register Lisp_Object val
;
2574 int count
= specpdl_ptr
- specpdl
;
2575 int beg
, end
, change
;
2579 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2581 Fset_buffer (combine_after_change_buffer
);
2583 /* # chars unchanged at beginning of buffer. */
2585 /* # chars unchanged at end of buffer. */
2587 /* Total amount of insertion (negative for deletion). */
2590 /* Scan the various individual changes,
2591 accumulating the range info in BEG, END and CHANGE. */
2592 for (tail
= combine_after_change_list
; CONSP (tail
);
2593 tail
= XCONS (tail
)->cdr
)
2596 int thisbeg
, thisend
, thischange
;
2598 /* Extract the info from the next element. */
2599 elt
= XCONS (tail
)->car
;
2602 thisbeg
= XINT (XCONS (elt
)->car
);
2604 elt
= XCONS (elt
)->cdr
;
2607 thisend
= XINT (XCONS (elt
)->car
);
2609 elt
= XCONS (elt
)->cdr
;
2612 thischange
= XINT (XCONS (elt
)->car
);
2614 /* Merge this range into the accumulated range. */
2615 change
+= thischange
;
2622 /* Get the current start and end positions of the range
2623 that was changed. */
2627 /* We are about to handle these, so discard them. */
2628 combine_after_change_list
= Qnil
;
2630 /* Now run the after-change functions for real.
2631 Turn off the flag that defers them. */
2632 record_unwind_protect (Fcombine_after_change_execute_1
,
2633 Vcombine_after_change_calls
);
2634 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2636 return unbind_to (count
, val
);
2642 staticpro (&combine_after_change_list
);
2643 combine_after_change_list
= Qnil
;
2645 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag
,
2646 "Non-nil means enable debugging checks for invalid marker positions.");
2647 check_markers_debug_flag
= 0;
2648 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls
,
2649 "Used internally by the `combine-after-change-calls' macro.");
2650 Vcombine_after_change_calls
= Qnil
;
2652 defsubr (&Scombine_after_change_execute
);