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
);
1032 /* If we are going to combine bytes at POS which is at a narrowed
1033 region boundary, signal an error. */
1034 #define CHECK_BYTE_COMBINING_FOR_INSERT(pos) \
1036 if (combined_before_bytes && pos == BEGV \
1037 || combined_after_bytes && pos == ZV) \
1038 error ("Byte combining across region boundary inhibitted"); \
1042 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1043 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
1044 are the same as in insert_1. */
1047 insert_1_both (string
, nchars
, nbytes
, inherit
, prepare
, before_markers
)
1048 register unsigned char *string
;
1049 register int nchars
, nbytes
;
1050 int inherit
, prepare
, before_markers
;
1052 register Lisp_Object temp
;
1053 int combined_before_bytes
, combined_after_bytes
;
1055 if (NILP (current_buffer
->enable_multibyte_characters
))
1059 /* Do this before moving and increasing the gap,
1060 because the before-change hooks might move the gap
1061 or make it smaller. */
1062 prepare_to_modify_buffer (PT
, PT
, NULL
);
1065 move_gap_both (PT
, PT_BYTE
);
1066 if (GAP_SIZE
< nbytes
)
1067 make_gap (nbytes
- GAP_SIZE
);
1069 combined_before_bytes
1070 = count_combining_before (string
, nbytes
, PT
, PT_BYTE
);
1071 combined_after_bytes
1072 = count_combining_after (string
, nbytes
, PT
, PT_BYTE
);
1073 CHECK_BYTE_COMBINING_FOR_INSERT (PT
);
1075 /* Record deletion of the surrounding text that combines with
1076 the insertion. This, together with recording the insertion,
1077 will add up to the right stuff in the undo list.
1079 But there is no need to actually delete the combining bytes
1080 from the buffer and reinsert them. */
1082 if (combined_after_bytes
)
1084 Lisp_Object deletion
;
1087 if (! EQ (current_buffer
->undo_list
, Qt
))
1088 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1089 PT
+ combined_after_bytes
,
1090 PT_BYTE
+ combined_after_bytes
, 1);
1092 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1093 PT
+ combined_after_bytes
,
1094 PT_BYTE
+ combined_after_bytes
);
1095 if (! EQ (current_buffer
->undo_list
, Qt
))
1096 record_delete (PT
, deletion
);
1099 if (combined_before_bytes
)
1101 Lisp_Object deletion
;
1104 if (! EQ (current_buffer
->undo_list
, Qt
))
1105 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1107 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1109 if (! EQ (current_buffer
->undo_list
, Qt
))
1110 record_delete (PT
- 1, deletion
);
1113 record_insert (PT
- !!combined_before_bytes
,
1114 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1117 bcopy (string
, GPT_ADDR
, nbytes
);
1120 /* When we have combining at the end of the insertion,
1121 this is the character position before the combined character. */
1128 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1130 if (combined_after_bytes
)
1131 move_gap_both (GPT
+ combined_after_bytes
,
1132 GPT_BYTE
+ combined_after_bytes
);
1137 adjust_overlays_for_insert (PT
, nchars
);
1138 adjust_markers_for_insert (PT
, PT_BYTE
,
1139 PT
+ nchars
, PT_BYTE
+ nbytes
,
1140 combined_before_bytes
, combined_after_bytes
,
1143 #ifdef USE_TEXT_PROPERTIES
1144 if (BUF_INTERVALS (current_buffer
) != 0)
1145 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
1146 offset_intervals (current_buffer
, PT
, nchars
);
1148 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
1149 Fset_text_properties (make_number (PT
), make_number (PT
+ nchars
),
1154 int pos
= PT
, pos_byte
= PT_BYTE
;
1156 adjust_point (nchars
+ combined_after_bytes
,
1157 nbytes
+ combined_after_bytes
);
1159 if (combined_after_bytes
)
1160 combine_bytes (pos
+ nchars
, pos_byte
+ nbytes
, combined_after_bytes
);
1162 if (combined_before_bytes
)
1163 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1169 /* Insert the part of the text of STRING, a Lisp object assumed to be
1170 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1171 starting at position POS / POS_BYTE. If the text of STRING has properties,
1172 copy them into the buffer.
1174 It does not work to use `insert' for this, because a GC could happen
1175 before we bcopy the stuff into the buffer, and relocate the string
1176 without insert noticing. */
1179 insert_from_string (string
, pos
, pos_byte
, length
, length_byte
, inherit
)
1181 register int pos
, pos_byte
, length
, length_byte
;
1185 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1187 signal_after_change (opoint
, 0, PT
- opoint
);
1190 /* Like `insert_from_string' except that all markers pointing
1191 at the place where the insertion happens are adjusted to point after it. */
1194 insert_from_string_before_markers (string
, pos
, pos_byte
,
1195 length
, length_byte
, inherit
)
1197 register int pos
, pos_byte
, length
, length_byte
;
1201 insert_from_string_1 (string
, pos
, pos_byte
, length
, length_byte
,
1203 signal_after_change (opoint
, 0, PT
- opoint
);
1206 /* Subroutine of the insertion functions above. */
1209 insert_from_string_1 (string
, pos
, pos_byte
, nchars
, nbytes
,
1210 inherit
, before_markers
)
1212 register int pos
, pos_byte
, nchars
, nbytes
;
1213 int inherit
, before_markers
;
1215 register Lisp_Object temp
;
1216 struct gcpro gcpro1
;
1217 int outgoing_nbytes
= nbytes
;
1218 int combined_before_bytes
, combined_after_bytes
;
1219 int adjusted_nchars
;
1222 /* Make OUTGOING_NBYTES describe the text
1223 as it will be inserted in this buffer. */
1225 if (NILP (current_buffer
->enable_multibyte_characters
))
1226 outgoing_nbytes
= nchars
;
1227 else if (! STRING_MULTIBYTE (string
))
1229 = count_size_as_multibyte (&XSTRING (string
)->data
[pos_byte
],
1233 /* Do this before moving and increasing the gap,
1234 because the before-change hooks might move the gap
1235 or make it smaller. */
1236 prepare_to_modify_buffer (PT
, PT
, NULL
);
1239 move_gap_both (PT
, PT_BYTE
);
1240 if (GAP_SIZE
< nbytes
)
1241 make_gap (outgoing_nbytes
- GAP_SIZE
);
1244 /* Copy the string text into the buffer, perhaps converting
1245 between single-byte and multibyte. */
1246 copy_text (XSTRING (string
)->data
+ pos_byte
, GPT_ADDR
, nbytes
,
1247 STRING_MULTIBYTE (string
),
1248 ! NILP (current_buffer
->enable_multibyte_characters
));
1250 /* We have copied text into the gap, but we have not altered
1251 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1252 to these functions and get the same results as we would
1253 have got earlier on. Meanwhile, PT_ADDR does point to
1254 the text that has been stored by copy_text. */
1256 combined_before_bytes
1257 = count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1258 combined_after_bytes
1259 = count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1261 unsigned char save
= *(GPT_ADDR
);
1262 CHECK_BYTE_COMBINING_FOR_INSERT (PT
);
1266 /* Record deletion of the surrounding text that combines with
1267 the insertion. This, together with recording the insertion,
1268 will add up to the right stuff in the undo list.
1270 But there is no need to actually delete the combining bytes
1271 from the buffer and reinsert them. */
1273 if (combined_after_bytes
)
1275 Lisp_Object deletion
;
1278 if (! EQ (current_buffer
->undo_list
, Qt
))
1279 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1280 PT
+ combined_after_bytes
,
1281 PT_BYTE
+ combined_after_bytes
, 1);
1283 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1284 PT
+ combined_after_bytes
,
1285 PT_BYTE
+ combined_after_bytes
);
1286 if (! EQ (current_buffer
->undo_list
, Qt
))
1287 record_delete (PT
, deletion
);
1290 if (combined_before_bytes
)
1292 Lisp_Object deletion
;
1295 if (! EQ (current_buffer
->undo_list
, Qt
))
1296 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1298 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1300 if (! EQ (current_buffer
->undo_list
, Qt
))
1301 record_delete (PT
- 1, deletion
);
1304 record_insert (PT
- !!combined_before_bytes
,
1305 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1308 GAP_SIZE
-= outgoing_nbytes
;
1312 GPT_BYTE
+= outgoing_nbytes
;
1313 ZV_BYTE
+= outgoing_nbytes
;
1314 Z_BYTE
+= outgoing_nbytes
;
1315 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1317 if (combined_after_bytes
)
1318 move_gap_both (GPT
+ combined_after_bytes
,
1319 GPT_BYTE
+ combined_after_bytes
);
1324 adjust_overlays_for_insert (PT
, nchars
);
1325 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1326 PT_BYTE
+ outgoing_nbytes
,
1327 combined_before_bytes
, combined_after_bytes
,
1330 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1331 offset_intervals (current_buffer
, PT
, nchars
);
1333 intervals
= XSTRING (string
)->intervals
;
1334 /* Get the intervals for the part of the string we are inserting--
1335 not including the combined-before bytes. */
1336 if (nbytes
< STRING_BYTES (XSTRING (string
)))
1337 intervals
= copy_intervals (intervals
, pos
, nchars
);
1339 /* Insert those intervals. */
1340 graft_intervals_into_buffer (intervals
, PT
, nchars
,
1341 current_buffer
, inherit
);
1344 int pos
= PT
, pos_byte
= PT_BYTE
;
1346 adjust_point (nchars
+ combined_after_bytes
,
1347 outgoing_nbytes
+ combined_after_bytes
);
1349 if (combined_after_bytes
)
1350 combine_bytes (pos
+ nchars
, pos_byte
+ outgoing_nbytes
,
1351 combined_after_bytes
);
1353 if (combined_before_bytes
)
1354 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1358 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1359 current buffer. If the text in BUF has properties, they are absorbed
1360 into the current buffer.
1362 It does not work to use `insert' for this, because a malloc could happen
1363 and relocate BUF's text before the bcopy happens. */
1366 insert_from_buffer (buf
, charpos
, nchars
, inherit
)
1368 int charpos
, nchars
;
1373 insert_from_buffer_1 (buf
, charpos
, nchars
, inherit
);
1374 signal_after_change (opoint
, 0, PT
- opoint
);
1378 insert_from_buffer_1 (buf
, from
, nchars
, inherit
)
1383 register Lisp_Object temp
;
1385 int from_byte
= buf_charpos_to_bytepos (buf
, from
);
1386 int to_byte
= buf_charpos_to_bytepos (buf
, from
+ nchars
);
1387 int incoming_nbytes
= to_byte
- from_byte
;
1388 int outgoing_nbytes
= incoming_nbytes
;
1389 int combined_before_bytes
, combined_after_bytes
;
1390 int adjusted_nchars
;
1393 /* Make OUTGOING_NBYTES describe the text
1394 as it will be inserted in this buffer. */
1396 if (NILP (current_buffer
->enable_multibyte_characters
))
1397 outgoing_nbytes
= nchars
;
1398 else if (NILP (buf
->enable_multibyte_characters
))
1400 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf
, from_byte
),
1403 /* Make sure point-max won't overflow after this insertion. */
1404 XSETINT (temp
, outgoing_nbytes
+ Z
);
1405 if (outgoing_nbytes
+ Z
!= XINT (temp
))
1406 error ("Maximum buffer size exceeded");
1408 /* Do this before moving and increasing the gap,
1409 because the before-change hooks might move the gap
1410 or make it smaller. */
1411 prepare_to_modify_buffer (PT
, PT
, NULL
);
1414 move_gap_both (PT
, PT_BYTE
);
1415 if (GAP_SIZE
< outgoing_nbytes
)
1416 make_gap (outgoing_nbytes
- GAP_SIZE
);
1418 if (from
< BUF_GPT (buf
))
1420 chunk
= BUF_GPT_BYTE (buf
) - from_byte
;
1421 if (chunk
> incoming_nbytes
)
1422 chunk
= incoming_nbytes
;
1423 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
),
1425 ! NILP (buf
->enable_multibyte_characters
),
1426 ! NILP (current_buffer
->enable_multibyte_characters
));
1430 if (chunk
< incoming_nbytes
)
1431 copy_text (BUF_BYTE_ADDRESS (buf
, from_byte
+ chunk
),
1432 GPT_ADDR
+ chunk
, incoming_nbytes
- chunk
,
1433 ! NILP (buf
->enable_multibyte_characters
),
1434 ! NILP (current_buffer
->enable_multibyte_characters
));
1436 /* We have copied text into the gap, but we have not altered
1437 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1438 to these functions and get the same results as we would
1439 have got earlier on. Meanwhile, GPT_ADDR does point to
1440 the text that has been stored by copy_text. */
1441 combined_before_bytes
1442 = count_combining_before (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1443 combined_after_bytes
1444 = count_combining_after (GPT_ADDR
, outgoing_nbytes
, PT
, PT_BYTE
);
1446 unsigned char save
= *(GPT_ADDR
);
1447 CHECK_BYTE_COMBINING_FOR_INSERT (PT
);
1451 /* Record deletion of the surrounding text that combines with
1452 the insertion. This, together with recording the insertion,
1453 will add up to the right stuff in the undo list.
1455 But there is no need to actually delete the combining bytes
1456 from the buffer and reinsert them. */
1458 if (combined_after_bytes
)
1460 Lisp_Object deletion
;
1463 if (! EQ (current_buffer
->undo_list
, Qt
))
1464 deletion
= make_buffer_string_both (PT
, PT_BYTE
,
1465 PT
+ combined_after_bytes
,
1466 PT_BYTE
+ combined_after_bytes
, 1);
1468 adjust_markers_for_record_delete (PT
, PT_BYTE
,
1469 PT
+ combined_after_bytes
,
1470 PT_BYTE
+ combined_after_bytes
);
1471 if (! EQ (current_buffer
->undo_list
, Qt
))
1472 record_delete (PT
, deletion
);
1475 if (combined_before_bytes
)
1477 Lisp_Object deletion
;
1480 if (! EQ (current_buffer
->undo_list
, Qt
))
1481 deletion
= make_buffer_string_both (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1483 adjust_markers_for_record_delete (PT
- 1, CHAR_TO_BYTE (PT
- 1),
1485 if (! EQ (current_buffer
->undo_list
, Qt
))
1486 record_delete (PT
- 1, deletion
);
1489 record_insert (PT
- !!combined_before_bytes
,
1490 nchars
- combined_before_bytes
+ !!combined_before_bytes
);
1493 GAP_SIZE
-= outgoing_nbytes
;
1497 GPT_BYTE
+= outgoing_nbytes
;
1498 ZV_BYTE
+= outgoing_nbytes
;
1499 Z_BYTE
+= outgoing_nbytes
;
1500 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1502 if (combined_after_bytes
)
1503 move_gap_both (GPT
+ combined_after_bytes
,
1504 GPT_BYTE
+ combined_after_bytes
);
1509 adjust_overlays_for_insert (PT
, nchars
);
1510 adjust_markers_for_insert (PT
, PT_BYTE
, PT
+ nchars
,
1511 PT_BYTE
+ outgoing_nbytes
,
1512 combined_before_bytes
, combined_after_bytes
, 0);
1514 #ifdef USE_TEXT_PROPERTIES
1515 if (BUF_INTERVALS (current_buffer
) != 0)
1516 offset_intervals (current_buffer
, PT
, nchars
);
1519 /* Get the intervals for the part of the string we are inserting--
1520 not including the combined-before bytes. */
1521 intervals
= BUF_INTERVALS (buf
);
1522 if (outgoing_nbytes
< BUF_Z_BYTE (buf
) - BUF_BEG_BYTE (buf
))
1523 intervals
= copy_intervals (intervals
, from
, nchars
);
1525 /* Insert those intervals. */
1526 graft_intervals_into_buffer (intervals
, PT
, nchars
, current_buffer
, inherit
);
1529 int pos
= PT
, pos_byte
= PT_BYTE
;
1531 adjust_point (nchars
+ combined_after_bytes
,
1532 outgoing_nbytes
+ combined_after_bytes
);
1534 if (combined_after_bytes
)
1535 combine_bytes (pos
+ nchars
, pos_byte
+ outgoing_nbytes
,
1536 combined_after_bytes
);
1538 if (combined_before_bytes
)
1539 combine_bytes (pos
, pos_byte
, combined_before_bytes
);
1543 /* This function should be called after moving gap to FROM and before
1544 altering text between FROM and TO. This adjusts various position
1545 keepers and markers as if the text is deleted. Don't forget to
1546 call adjust_after_replace after you actually alter the text. */
1549 adjust_before_replace (from
, from_byte
, to
, to_byte
)
1550 int from
, from_byte
, to
, to_byte
;
1552 Lisp_Object deletion
;
1554 if (! EQ (current_buffer
->undo_list
, Qt
))
1555 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1559 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1561 if (! EQ (current_buffer
->undo_list
, Qt
))
1562 record_delete (from
, deletion
);
1564 adjust_overlays_for_delete (from
, to
- from
);
1567 /* Record undo information and adjust markers and position keepers for
1568 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1569 chars (LEN_BYTE bytes) which resides in the gap just after
1572 PREV_TEXT nil means the new text was just inserted. */
1575 adjust_after_replace (from
, from_byte
, prev_text
, len
, len_byte
)
1576 int from
, from_byte
, len
, len_byte
;
1577 Lisp_Object prev_text
;
1579 int combined_before_bytes
1580 = count_combining_before (GPT_ADDR
, len_byte
, from
, from_byte
);
1581 int combined_after_bytes
1582 = count_combining_after (GPT_ADDR
, len_byte
, from
, from_byte
);
1583 int nchars_del
= 0, nbytes_del
= 0;
1585 if (STRINGP (prev_text
))
1587 nchars_del
= XSTRING (prev_text
)->size
;
1588 nbytes_del
= STRING_BYTES (XSTRING (prev_text
));
1591 if (combined_before_bytes
&& from
== BEGV
1592 || combined_after_bytes
&& from
== ZV
)
1594 /* We can't combine bytes nor signal an error here. So, let's
1595 pretend that the new text is just a single space. */
1597 combined_before_bytes
= combined_after_bytes
= 0;
1601 if (combined_after_bytes
)
1603 Lisp_Object deletion
;
1606 if (! EQ (current_buffer
->undo_list
, Qt
))
1607 deletion
= make_buffer_string_both (from
, from_byte
,
1608 from
+ combined_after_bytes
,
1609 from_byte
+ combined_after_bytes
,
1612 adjust_markers_for_record_delete (from
, from_byte
,
1613 from
+ combined_after_bytes
,
1614 from_byte
+ combined_after_bytes
);
1616 if (! EQ (current_buffer
->undo_list
, Qt
))
1617 record_delete (from
+ nchars_del
, deletion
);
1620 if (combined_before_bytes
1621 || len_byte
== 0 && combined_after_bytes
> 0)
1623 Lisp_Object deletion
;
1626 if (! EQ (current_buffer
->undo_list
, Qt
))
1627 deletion
= make_buffer_string_both (from
- 1, CHAR_TO_BYTE (from
- 1),
1628 from
, from_byte
, 1);
1629 adjust_markers_for_record_delete (from
- 1, CHAR_TO_BYTE (from
- 1),
1631 if (! EQ (current_buffer
->undo_list
, Qt
))
1632 record_delete (from
- 1, deletion
);
1635 /* Update various buffer positions for the new text. */
1636 GAP_SIZE
-= len_byte
;
1638 ZV_BYTE
+= len_byte
; Z_BYTE
+= len_byte
;
1639 GPT
+= len
; GPT_BYTE
+= len_byte
;
1640 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1642 /* The gap should be at character boundary. */
1643 if (combined_after_bytes
)
1644 move_gap_both (GPT
+ combined_after_bytes
,
1645 GPT_BYTE
+ combined_after_bytes
);
1647 adjust_markers_for_replace (from
, from_byte
, nchars_del
, nbytes_del
,
1649 combined_before_bytes
, combined_after_bytes
);
1650 if (! EQ (current_buffer
->undo_list
, Qt
))
1652 /* This flag tells if we combine some bytes with a character
1653 before FROM. This happens even if combined_before_bytes is
1655 int combine_before
= (combined_before_bytes
1656 || (len
== 0 && combined_after_bytes
));
1659 record_delete (from
- combine_before
, prev_text
);
1661 record_insert (from
- 1, len
- combined_before_bytes
+ 1);
1663 record_insert (from
, len
);
1666 if (len
> nchars_del
)
1667 adjust_overlays_for_insert (from
, len
- nchars_del
);
1668 else if (len
< nchars_del
)
1669 adjust_overlays_for_delete (from
, nchars_del
- len
);
1670 #ifdef USE_TEXT_PROPERTIES
1671 if (BUF_INTERVALS (current_buffer
) != 0)
1673 offset_intervals (current_buffer
, from
, len
- nchars_del
);
1678 int pos
= PT
, pos_byte
= PT_BYTE
;
1681 adjust_point (len
- nchars_del
, len_byte
- nbytes_del
);
1683 if (combined_after_bytes
)
1685 if (combined_before_bytes
== len_byte
)
1686 /* This is the case that all new bytes are combined. */
1687 combined_before_bytes
+= combined_after_bytes
;
1689 combine_bytes (from
+ len
, from_byte
+ len_byte
,
1690 combined_after_bytes
);
1692 if (combined_before_bytes
)
1693 combine_bytes (from
, from_byte
, combined_before_bytes
);
1696 /* As byte combining will decrease Z, we must check this again. */
1697 if (Z
- GPT
< end_unchanged
)
1698 end_unchanged
= Z
- GPT
;
1703 evaporate_overlays (from
);
1707 /* Record undo information, adjust markers and position keepers for an
1708 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1709 text already exists in the current buffer but character length (TO
1710 - FROM) may be incorrect, the correct length is NEWLEN. */
1713 adjust_after_insert (from
, from_byte
, to
, to_byte
, newlen
)
1714 int from
, from_byte
, to
, to_byte
, newlen
;
1716 int len
= to
- from
, len_byte
= to_byte
- from_byte
;
1719 move_gap_both (to
, to_byte
);
1720 GAP_SIZE
+= len_byte
;
1721 GPT
-= len
; GPT_BYTE
-= len_byte
;
1722 ZV
-= len
; ZV_BYTE
-= len_byte
;
1723 Z
-= len
; Z_BYTE
-= len_byte
;
1724 adjust_after_replace (from
, from_byte
, Qnil
, newlen
, len_byte
);
1727 /* Replace the text from character positions FROM to TO with NEW,
1728 If PREPARE is nonzero, call prepare_to_modify_buffer.
1729 If INHERIT, the newly inserted text should inherit text properties
1730 from the surrounding non-deleted text. */
1732 /* Note that this does not yet handle markers quite right.
1733 Also it needs to record a single undo-entry that does a replacement
1734 rather than a separate delete and insert.
1735 That way, undo will also handle markers properly.
1737 But if MARKERS is 0, don't relocate markers. */
1740 replace_range (from
, to
, new, prepare
, inherit
, markers
)
1742 int from
, to
, prepare
, inherit
, markers
;
1744 int inschars
= XSTRING (new)->size
;
1745 int insbytes
= STRING_BYTES (XSTRING (new));
1746 int from_byte
, to_byte
;
1747 int nbytes_del
, nchars_del
;
1748 register Lisp_Object temp
;
1749 struct gcpro gcpro1
;
1750 int combined_before_bytes
, combined_after_bytes
;
1751 int adjusted_inschars
;
1753 int outgoing_insbytes
= insbytes
;
1754 Lisp_Object deletion
;
1762 int range_length
= to
- from
;
1763 prepare_to_modify_buffer (from
, to
, &from
);
1764 to
= from
+ range_length
;
1769 /* Make args be valid */
1775 from_byte
= CHAR_TO_BYTE (from
);
1776 to_byte
= CHAR_TO_BYTE (to
);
1778 nchars_del
= to
- from
;
1779 nbytes_del
= to_byte
- from_byte
;
1781 if (nbytes_del
<= 0 && insbytes
== 0)
1784 /* Make OUTGOING_INSBYTES describe the text
1785 as it will be inserted in this buffer. */
1787 if (NILP (current_buffer
->enable_multibyte_characters
))
1788 outgoing_insbytes
= inschars
;
1789 else if (! STRING_MULTIBYTE (new))
1791 = count_size_as_multibyte (XSTRING (new)->data
, insbytes
);
1793 /* Make sure point-max won't overflow after this insertion. */
1794 XSETINT (temp
, Z_BYTE
- nbytes_del
+ insbytes
);
1795 if (Z_BYTE
- nbytes_del
+ insbytes
!= XINT (temp
))
1796 error ("Maximum buffer size exceeded");
1800 /* Make sure the gap is somewhere in or next to what we are deleting. */
1802 gap_right (from
, from_byte
);
1804 gap_left (to
, to_byte
, 0);
1808 if (! EQ (current_buffer
->undo_list
, Qt
))
1809 deletion
= make_buffer_string_both (from
, from_byte
, to
, to_byte
, 1);
1812 /* Relocate all markers pointing into the new, larger gap
1813 to point at the end of the text before the gap.
1814 Do this before recording the deletion,
1815 so that undo handles this after reinserting the text. */
1816 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
1818 GAP_SIZE
+= nbytes_del
;
1821 ZV_BYTE
-= nbytes_del
;
1822 Z_BYTE
-= nbytes_del
;
1824 GPT_BYTE
= from_byte
;
1825 *(GPT_ADDR
) = 0; /* Put an anchor. */
1830 if (GPT
- BEG
< beg_unchanged
)
1831 beg_unchanged
= GPT
- BEG
;
1832 if (Z
- GPT
< end_unchanged
)
1833 end_unchanged
= Z
- GPT
;
1835 if (GAP_SIZE
< insbytes
)
1836 make_gap (insbytes
- GAP_SIZE
);
1838 /* Copy the string text into the buffer, perhaps converting
1839 between single-byte and multibyte. */
1840 copy_text (XSTRING (new)->data
, GPT_ADDR
, insbytes
,
1841 STRING_MULTIBYTE (new),
1842 ! NILP (current_buffer
->enable_multibyte_characters
));
1844 /* We have copied text into the gap, but we have not marked
1845 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1846 here, for both the previous text and the following text.
1847 Meanwhile, GPT_ADDR does point to
1848 the text that has been stored by copy_text. */
1850 combined_before_bytes
1851 = count_combining_before (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
);
1852 combined_after_bytes
1853 = count_combining_after (GPT_ADDR
, outgoing_insbytes
, from
, from_byte
);
1855 unsigned char save
= *(GPT_ADDR
);
1856 CHECK_BYTE_COMBINING_FOR_INSERT (from
);
1860 /* Record deletion of the surrounding text that combines with
1861 the insertion. This, together with recording the insertion,
1862 will add up to the right stuff in the undo list.
1864 But there is no need to actually delete the combining bytes
1865 from the buffer and reinsert them. */
1867 if (combined_after_bytes
)
1869 Lisp_Object deletion
;
1872 if (! EQ (current_buffer
->undo_list
, Qt
))
1873 deletion
= make_buffer_string_both (from
, from_byte
,
1874 from
+ combined_after_bytes
,
1875 from_byte
+ combined_after_bytes
,
1878 adjust_markers_for_record_delete (from
, from_byte
,
1879 from
+ combined_after_bytes
,
1880 from_byte
+ combined_after_bytes
);
1881 if (! EQ (current_buffer
->undo_list
, Qt
))
1882 record_delete (from
+ nchars_del
, deletion
);
1885 if (combined_before_bytes
)
1887 Lisp_Object deletion
;
1890 if (! EQ (current_buffer
->undo_list
, Qt
))
1891 deletion
= make_buffer_string_both (from
- 1, CHAR_TO_BYTE (from
- 1),
1892 from
, from_byte
, 1);
1893 adjust_markers_for_record_delete (from
- 1, CHAR_TO_BYTE (from
- 1),
1895 if (! EQ (current_buffer
->undo_list
, Qt
))
1896 record_delete (from
- 1, deletion
);
1899 if (! EQ (current_buffer
->undo_list
, Qt
))
1901 record_delete (from
- !!combined_before_bytes
, deletion
);
1902 record_insert (from
- !!combined_before_bytes
,
1903 (inschars
- combined_before_bytes
1904 + !!combined_before_bytes
));
1907 GAP_SIZE
-= outgoing_insbytes
;
1911 GPT_BYTE
+= outgoing_insbytes
;
1912 ZV_BYTE
+= outgoing_insbytes
;
1913 Z_BYTE
+= outgoing_insbytes
;
1914 if (GAP_SIZE
> 0) *(GPT_ADDR
) = 0; /* Put an anchor. */
1916 if (combined_after_bytes
)
1917 move_gap_both (GPT
+ combined_after_bytes
,
1918 GPT_BYTE
+ combined_after_bytes
);
1923 /* Adjust the overlay center as needed. This must be done after
1924 adjusting the markers that bound the overlays. */
1925 adjust_overlays_for_delete (from
, nchars_del
);
1926 adjust_overlays_for_insert (from
, inschars
);
1928 adjust_markers_for_insert (from
, from_byte
,
1929 from
+ inschars
, from_byte
+ outgoing_insbytes
,
1930 combined_before_bytes
, combined_after_bytes
, 0);
1932 #ifdef USE_TEXT_PROPERTIES
1933 offset_intervals (current_buffer
, from
, inschars
- nchars_del
);
1935 /* Get the intervals for the part of the string we are inserting--
1936 not including the combined-before bytes. */
1937 intervals
= XSTRING (new)->intervals
;
1938 /* Insert those intervals. */
1939 graft_intervals_into_buffer (intervals
, from
, inschars
,
1940 current_buffer
, inherit
);
1943 /* Relocate point as if it were a marker. */
1945 adjust_point ((from
+ inschars
- (PT
< to
? PT
: to
)),
1946 (from_byte
+ outgoing_insbytes
1947 - (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
)));
1949 if (combined_after_bytes
)
1951 if (combined_before_bytes
== outgoing_insbytes
)
1952 /* This is the case that all new bytes are combined. */
1953 combined_before_bytes
+= combined_after_bytes
;
1955 combine_bytes (from
+ inschars
, from_byte
+ outgoing_insbytes
,
1956 combined_after_bytes
);
1958 if (combined_before_bytes
)
1959 combine_bytes (from
, from_byte
, combined_before_bytes
);
1961 /* As byte combining will decrease Z, we must check this again. */
1962 if (Z
- GPT
< end_unchanged
)
1963 end_unchanged
= Z
- GPT
;
1965 if (outgoing_insbytes
== 0)
1966 evaporate_overlays (from
);
1973 signal_after_change (from
, nchars_del
, GPT
- from
);
1976 /* Delete characters in current buffer
1977 from FROM up to (but not including) TO.
1978 If TO comes before FROM, we delete nothing. */
1981 del_range (from
, to
)
1982 register int from
, to
;
1984 del_range_1 (from
, to
, 1);
1987 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
1990 del_range_1 (from
, to
, prepare
)
1991 int from
, to
, prepare
;
1993 int from_byte
, to_byte
;
1995 /* Make args be valid */
2006 int range_length
= to
- from
;
2007 prepare_to_modify_buffer (from
, to
, &from
);
2008 to
= from
+ range_length
;
2011 from_byte
= CHAR_TO_BYTE (from
);
2012 to_byte
= CHAR_TO_BYTE (to
);
2014 del_range_2 (from
, from_byte
, to
, to_byte
);
2017 /* Like del_range_1 but args are byte positions, not char positions. */
2020 del_range_byte (from_byte
, to_byte
, prepare
)
2021 int from_byte
, to_byte
, prepare
;
2025 /* Make args be valid */
2026 if (from_byte
< BEGV_BYTE
)
2027 from_byte
= BEGV_BYTE
;
2028 if (to_byte
> ZV_BYTE
)
2031 if (to_byte
<= from_byte
)
2034 from
= BYTE_TO_CHAR (from_byte
);
2035 to
= BYTE_TO_CHAR (to_byte
);
2039 int old_from
= from
, old_to
= Z
- to
;
2040 int range_length
= to
- from
;
2041 prepare_to_modify_buffer (from
, to
, &from
);
2042 to
= from
+ range_length
;
2044 if (old_from
!= from
)
2045 from_byte
= CHAR_TO_BYTE (from
);
2046 if (old_to
== Z
- to
)
2047 to_byte
= CHAR_TO_BYTE (to
);
2050 del_range_2 (from
, from_byte
, to
, to_byte
);
2053 /* Like del_range_1, but positions are specified both as charpos
2057 del_range_both (from
, from_byte
, to
, to_byte
, prepare
)
2058 int from
, from_byte
, to
, to_byte
, prepare
;
2060 /* Make args be valid */
2061 if (from_byte
< BEGV_BYTE
)
2062 from_byte
= BEGV_BYTE
;
2063 if (to_byte
> ZV_BYTE
)
2066 if (to_byte
<= from_byte
)
2076 int old_from
= from
, old_to
= Z
- to
;
2077 int range_length
= to
- from
;
2078 prepare_to_modify_buffer (from
, to
, &from
);
2079 to
= from
+ range_length
;
2081 if (old_from
!= from
)
2082 from_byte
= CHAR_TO_BYTE (from
);
2083 if (old_to
== Z
- to
)
2084 to_byte
= CHAR_TO_BYTE (to
);
2087 del_range_2 (from
, from_byte
, to
, to_byte
);
2090 /* Delete a range of text, specified both as character positions
2091 and byte positions. FROM and TO are character positions,
2092 while FROM_BYTE and TO_BYTE are byte positions. */
2095 del_range_2 (from
, from_byte
, to
, to_byte
)
2096 int from
, from_byte
, to
, to_byte
;
2098 register int nbytes_del
, nchars_del
;
2099 int combined_after_bytes
;
2100 Lisp_Object deletion
;
2105 nchars_del
= to
- from
;
2106 nbytes_del
= to_byte
- from_byte
;
2108 /* Make sure the gap is somewhere in or next to what we are deleting. */
2110 gap_right (from
, from_byte
);
2112 gap_left (to
, to_byte
, 0);
2114 combined_after_bytes
2115 = count_combining_before (BUF_BYTE_ADDRESS (current_buffer
, to_byte
),
2116 Z_BYTE
- to_byte
, from
, from_byte
);
2117 if (combined_after_bytes
)
2120 error ("Byte combining across region boundary inhibitted");
2121 from_byte_1
= from_byte
;
2122 DEC_POS (from_byte_1
);
2125 from_byte_1
= from_byte
;
2127 if (! EQ (current_buffer
->undo_list
, Qt
))
2129 = make_buffer_string_both (from
- !!combined_after_bytes
,
2131 to
+ combined_after_bytes
,
2132 to_byte
+ combined_after_bytes
, 1);
2133 if (combined_after_bytes
)
2134 /* COMBINED_AFTER_BYTES nonzero means that the above code moved
2135 the gap. We must move the gap again to a proper place. */
2136 move_gap_both (from
, from_byte
);
2138 /* Relocate all markers pointing into the new, larger gap
2139 to point at the end of the text before the gap.
2140 Do this before recording the deletion,
2141 so that undo handles this after reinserting the text. */
2142 adjust_markers_for_delete (from
, from_byte
, to
, to_byte
);
2143 if (combined_after_bytes
)
2145 /* Adjust markers for the phony deletion
2146 that we are about to call record_undo for. */
2148 /* Here we delete the markers that formerly
2149 pointed at TO ... TO + COMBINED_AFTER_BYTES.
2150 But because of the call to adjust_markers_for_delete, above,
2151 they now point at FROM ... FROM + COMBINED_AFTER_BYTES. */
2152 adjust_markers_for_record_delete (from
, from_byte
,
2153 from
+ combined_after_bytes
,
2154 from_byte
+ combined_after_bytes
);
2156 adjust_markers_for_record_delete (from
- 1, from_byte_1
,
2159 if (! EQ (current_buffer
->undo_list
, Qt
))
2160 record_delete (from
- !!combined_after_bytes
, deletion
);
2163 /* Relocate point as if it were a marker. */
2165 adjust_point (from
- (PT
< to
? PT
: to
),
2166 from_byte
- (PT_BYTE
< to_byte
? PT_BYTE
: to_byte
));
2168 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
2169 offset_intervals (current_buffer
, from
, - nchars_del
);
2171 /* Adjust the overlay center as needed. This must be done after
2172 adjusting the markers that bound the overlays. */
2173 adjust_overlays_for_delete (from
, nchars_del
);
2175 GAP_SIZE
+= nbytes_del
;
2176 ZV_BYTE
-= nbytes_del
;
2177 Z_BYTE
-= nbytes_del
;
2181 GPT_BYTE
= from_byte
;
2183 if (combined_after_bytes
)
2184 move_gap_both (GPT
+ combined_after_bytes
,
2185 GPT_BYTE
+ combined_after_bytes
);
2187 *(GPT_ADDR
) = 0; /* Put an anchor. */
2192 if (GPT
- BEG
< beg_unchanged
)
2193 beg_unchanged
= GPT
- BEG
;
2194 if (Z
- GPT
< end_unchanged
)
2195 end_unchanged
= Z
- GPT
;
2197 if (combined_after_bytes
)
2199 /* Adjust markers for byte combining. As we have already
2200 adjuted markers without concerning byte combining, here we
2201 must concern only byte combining. */
2202 adjust_markers_for_replace (from
, from_byte
, 0, 0, 0, 0,
2203 0, combined_after_bytes
);
2204 combine_bytes (from
, from_byte
, combined_after_bytes
);
2206 record_insert (GPT
- 1, 1);
2208 if (Z
- GPT
< end_unchanged
)
2209 end_unchanged
= Z
- GPT
;
2214 evaporate_overlays (from
);
2215 signal_after_change (from
, nchars_del
, 0);
2218 /* Call this if you're about to change the region of BUFFER from
2219 character positions START to END. This checks the read-only
2220 properties of the region, calls the necessary modification hooks,
2221 and warns the next redisplay that it should pay attention to that
2225 modify_region (buffer
, start
, end
)
2226 struct buffer
*buffer
;
2229 struct buffer
*old_buffer
= current_buffer
;
2231 if (buffer
!= old_buffer
)
2232 set_buffer_internal (buffer
);
2234 prepare_to_modify_buffer (start
, end
, NULL
);
2236 if (start
- 1 < beg_unchanged
2237 || (unchanged_modified
== MODIFF
2238 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
2239 beg_unchanged
= start
- 1;
2240 if (Z
- end
< end_unchanged
2241 || (unchanged_modified
== MODIFF
2242 && overlay_unchanged_modified
== OVERLAY_MODIFF
))
2243 end_unchanged
= Z
- end
;
2245 if (MODIFF
<= SAVE_MODIFF
)
2246 record_first_change ();
2249 buffer
->point_before_scroll
= Qnil
;
2251 if (buffer
!= old_buffer
)
2252 set_buffer_internal (old_buffer
);
2255 /* Check that it is okay to modify the buffer between START and END,
2256 which are char positions.
2258 Run the before-change-function, if any. If intervals are in use,
2259 verify that the text to be modified is not read-only, and call
2260 any modification properties the text may have.
2262 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2263 by holding its value temporarily in a marker. */
2266 prepare_to_modify_buffer (start
, end
, preserve_ptr
)
2270 if (!NILP (current_buffer
->read_only
))
2271 Fbarf_if_buffer_read_only ();
2273 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
2274 if (BUF_INTERVALS (current_buffer
) != 0)
2278 Lisp_Object preserve_marker
;
2279 struct gcpro gcpro1
;
2280 preserve_marker
= Fcopy_marker (make_number (*preserve_ptr
), Qnil
);
2281 GCPRO1 (preserve_marker
);
2282 verify_interval_modification (current_buffer
, start
, end
);
2283 *preserve_ptr
= marker_position (preserve_marker
);
2284 unchain_marker (preserve_marker
);
2288 verify_interval_modification (current_buffer
, start
, end
);
2291 #ifdef CLASH_DETECTION
2292 if (!NILP (current_buffer
->file_truename
)
2293 /* Make binding buffer-file-name to nil effective. */
2294 && !NILP (current_buffer
->filename
)
2295 && SAVE_MODIFF
>= MODIFF
)
2296 lock_file (current_buffer
->file_truename
);
2298 /* At least warn if this file has changed on disk since it was visited. */
2299 if (!NILP (current_buffer
->filename
)
2300 && SAVE_MODIFF
>= MODIFF
2301 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2302 && !NILP (Ffile_exists_p (current_buffer
->filename
)))
2303 call1 (intern ("ask-user-about-supersession-threat"),
2304 current_buffer
->filename
);
2305 #endif /* not CLASH_DETECTION */
2307 signal_before_change (start
, end
, preserve_ptr
);
2309 if (current_buffer
->newline_cache
)
2310 invalidate_region_cache (current_buffer
,
2311 current_buffer
->newline_cache
,
2312 start
- BEG
, Z
- end
);
2313 if (current_buffer
->width_run_cache
)
2314 invalidate_region_cache (current_buffer
,
2315 current_buffer
->width_run_cache
,
2316 start
- BEG
, Z
- end
);
2318 Vdeactivate_mark
= Qt
;
2321 /* These macros work with an argument named `preserve_ptr'
2322 and a local variable named `preserve_marker'. */
2324 #define PRESERVE_VALUE \
2325 if (preserve_ptr && NILP (preserve_marker)) \
2326 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2328 #define RESTORE_VALUE \
2329 if (! NILP (preserve_marker)) \
2331 *preserve_ptr = marker_position (preserve_marker); \
2332 unchain_marker (preserve_marker); \
2335 #define PRESERVE_START_END \
2336 if (NILP (start_marker)) \
2337 start_marker = Fcopy_marker (start, Qnil); \
2338 if (NILP (end_marker)) \
2339 end_marker = Fcopy_marker (end, Qnil);
2341 #define FETCH_START \
2342 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2345 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2347 /* Signal a change to the buffer immediately before it happens.
2348 START_INT and END_INT are the bounds of the text to be changed.
2350 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2351 by holding its value temporarily in a marker. */
2354 signal_before_change (start_int
, end_int
, preserve_ptr
)
2355 int start_int
, end_int
;
2358 Lisp_Object start
, end
;
2359 Lisp_Object start_marker
, end_marker
;
2360 Lisp_Object preserve_marker
;
2361 struct gcpro gcpro1
, gcpro2
, gcpro3
;
2363 if (inhibit_modification_hooks
)
2366 start
= make_number (start_int
);
2367 end
= make_number (end_int
);
2368 preserve_marker
= Qnil
;
2369 start_marker
= Qnil
;
2371 GCPRO3 (preserve_marker
, start_marker
, end_marker
);
2373 /* If buffer is unmodified, run a special hook for that case. */
2374 if (SAVE_MODIFF
>= MODIFF
2375 && !NILP (Vfirst_change_hook
)
2376 && !NILP (Vrun_hooks
))
2380 call1 (Vrun_hooks
, Qfirst_change_hook
);
2383 /* Run the before-change-function if any.
2384 We don't bother "binding" this variable to nil
2385 because it is obsolete anyway and new code should not use it. */
2386 if (!NILP (Vbefore_change_function
))
2390 call2 (Vbefore_change_function
, FETCH_START
, FETCH_END
);
2393 /* Now run the before-change-functions if any. */
2394 if (!NILP (Vbefore_change_functions
))
2396 Lisp_Object args
[3];
2397 Lisp_Object before_change_functions
;
2398 Lisp_Object after_change_functions
;
2399 struct gcpro gcpro1
, gcpro2
;
2404 /* "Bind" before-change-functions and after-change-functions
2405 to nil--but in a way that errors don't know about.
2406 That way, if there's an error in them, they will stay nil. */
2407 before_change_functions
= Vbefore_change_functions
;
2408 after_change_functions
= Vafter_change_functions
;
2409 Vbefore_change_functions
= Qnil
;
2410 Vafter_change_functions
= Qnil
;
2411 GCPRO2 (before_change_functions
, after_change_functions
);
2413 /* Actually run the hook functions. */
2414 args
[0] = Qbefore_change_functions
;
2415 args
[1] = FETCH_START
;
2416 args
[2] = FETCH_END
;
2417 run_hook_list_with_args (before_change_functions
, 3, args
);
2419 /* "Unbind" the variables we "bound" to nil. */
2420 Vbefore_change_functions
= before_change_functions
;
2421 Vafter_change_functions
= after_change_functions
;
2425 if (!NILP (current_buffer
->overlays_before
)
2426 || !NILP (current_buffer
->overlays_after
))
2429 report_overlay_modification (FETCH_START
, FETCH_END
, 0,
2430 FETCH_START
, FETCH_END
, Qnil
);
2433 if (! NILP (start_marker
))
2434 free_marker (start_marker
);
2435 if (! NILP (end_marker
))
2436 free_marker (end_marker
);
2441 /* Signal a change immediately after it happens.
2442 CHARPOS is the character position of the start of the changed text.
2443 LENDEL is the number of characters of the text before the change.
2444 (Not the whole buffer; just the part that was changed.)
2445 LENINS is the number of characters in that part of the text
2446 after the change. */
2449 signal_after_change (charpos
, lendel
, lenins
)
2450 int charpos
, lendel
, lenins
;
2452 if (inhibit_modification_hooks
)
2455 /* If we are deferring calls to the after-change functions
2456 and there are no before-change functions,
2457 just record the args that we were going to use. */
2458 if (! NILP (Vcombine_after_change_calls
)
2459 && NILP (Vbefore_change_function
) && NILP (Vbefore_change_functions
)
2460 && NILP (current_buffer
->overlays_before
)
2461 && NILP (current_buffer
->overlays_after
))
2465 if (!NILP (combine_after_change_list
)
2466 && current_buffer
!= XBUFFER (combine_after_change_buffer
))
2467 Fcombine_after_change_execute ();
2469 elt
= Fcons (make_number (charpos
- BEG
),
2470 Fcons (make_number (Z
- (charpos
- lendel
+ lenins
)),
2471 Fcons (make_number (lenins
- lendel
), Qnil
)));
2472 combine_after_change_list
2473 = Fcons (elt
, combine_after_change_list
);
2474 combine_after_change_buffer
= Fcurrent_buffer ();
2479 if (!NILP (combine_after_change_list
))
2480 Fcombine_after_change_execute ();
2482 /* Run the after-change-function if any.
2483 We don't bother "binding" this variable to nil
2484 because it is obsolete anyway and new code should not use it. */
2485 if (!NILP (Vafter_change_function
))
2486 call3 (Vafter_change_function
,
2487 make_number (charpos
), make_number (charpos
+ lenins
),
2488 make_number (lendel
));
2490 if (!NILP (Vafter_change_functions
))
2492 Lisp_Object args
[4];
2493 Lisp_Object before_change_functions
;
2494 Lisp_Object after_change_functions
;
2495 struct gcpro gcpro1
, gcpro2
;
2497 /* "Bind" before-change-functions and after-change-functions
2498 to nil--but in a way that errors don't know about.
2499 That way, if there's an error in them, they will stay nil. */
2500 before_change_functions
= Vbefore_change_functions
;
2501 after_change_functions
= Vafter_change_functions
;
2502 Vbefore_change_functions
= Qnil
;
2503 Vafter_change_functions
= Qnil
;
2504 GCPRO2 (before_change_functions
, after_change_functions
);
2506 /* Actually run the hook functions. */
2507 args
[0] = Qafter_change_functions
;
2508 XSETFASTINT (args
[1], charpos
);
2509 XSETFASTINT (args
[2], charpos
+ lenins
);
2510 XSETFASTINT (args
[3], lendel
);
2511 run_hook_list_with_args (after_change_functions
,
2514 /* "Unbind" the variables we "bound" to nil. */
2515 Vbefore_change_functions
= before_change_functions
;
2516 Vafter_change_functions
= after_change_functions
;
2520 if (!NILP (current_buffer
->overlays_before
)
2521 || !NILP (current_buffer
->overlays_after
))
2522 report_overlay_modification (make_number (charpos
),
2523 make_number (charpos
+ lenins
),
2525 make_number (charpos
),
2526 make_number (charpos
+ lenins
),
2527 make_number (lendel
));
2529 /* After an insertion, call the text properties
2530 insert-behind-hooks or insert-in-front-hooks. */
2532 report_interval_modification (make_number (charpos
),
2533 make_number (charpos
+ lenins
));
2537 Fcombine_after_change_execute_1 (val
)
2540 Vcombine_after_change_calls
= val
;
2544 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute
,
2545 Scombine_after_change_execute
, 0, 0, 0,
2546 "This function is for use internally in `combine-after-change-calls'.")
2549 register Lisp_Object val
;
2550 int count
= specpdl_ptr
- specpdl
;
2551 int beg
, end
, change
;
2555 record_unwind_protect (Fset_buffer
, Fcurrent_buffer ());
2557 Fset_buffer (combine_after_change_buffer
);
2559 /* # chars unchanged at beginning of buffer. */
2561 /* # chars unchanged at end of buffer. */
2563 /* Total amount of insertion (negative for deletion). */
2566 /* Scan the various individual changes,
2567 accumulating the range info in BEG, END and CHANGE. */
2568 for (tail
= combine_after_change_list
; CONSP (tail
);
2569 tail
= XCONS (tail
)->cdr
)
2572 int thisbeg
, thisend
, thischange
;
2574 /* Extract the info from the next element. */
2575 elt
= XCONS (tail
)->car
;
2578 thisbeg
= XINT (XCONS (elt
)->car
);
2580 elt
= XCONS (elt
)->cdr
;
2583 thisend
= XINT (XCONS (elt
)->car
);
2585 elt
= XCONS (elt
)->cdr
;
2588 thischange
= XINT (XCONS (elt
)->car
);
2590 /* Merge this range into the accumulated range. */
2591 change
+= thischange
;
2598 /* Get the current start and end positions of the range
2599 that was changed. */
2603 /* We are about to handle these, so discard them. */
2604 combine_after_change_list
= Qnil
;
2606 /* Now run the after-change functions for real.
2607 Turn off the flag that defers them. */
2608 record_unwind_protect (Fcombine_after_change_execute_1
,
2609 Vcombine_after_change_calls
);
2610 signal_after_change (begpos
, endpos
- begpos
- change
, endpos
- begpos
);
2612 return unbind_to (count
, val
);
2618 staticpro (&combine_after_change_list
);
2619 combine_after_change_list
= Qnil
;
2621 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag
,
2622 "Non-nil means enable debugging checks for invalid marker positions.");
2623 check_markers_debug_flag
= 0;
2624 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls
,
2625 "Used internally by the `combine-after-change-calls' macro.");
2626 Vcombine_after_change_calls
= Qnil
;
2628 defsubr (&Scombine_after_change_execute
);