Merge from emacs--devo--0
[emacs.git] / src / insdel.c
blob0b10534db2f81882a2bbb522743231faab24f133
1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
23 #include <config.h>
24 #include "lisp.h"
25 #include "intervals.h"
26 #include "buffer.h"
27 #include "character.h"
28 #include "window.h"
29 #include "blockinput.h"
30 #include "region-cache.h"
32 #ifndef NULL
33 #define NULL 0
34 #endif
36 static void insert_from_string_1 P_ ((Lisp_Object, int, int, int, int, int, int));
37 static void insert_from_buffer_1 ();
38 static void gap_left P_ ((int, int, int));
39 static void gap_right P_ ((int, int));
40 static void adjust_markers_gap_motion P_ ((int, int, int));
41 static void adjust_markers_for_insert P_ ((int, int, int, int, int));
42 void adjust_markers_for_delete P_ ((int, int, int, int));
43 static void adjust_markers_for_replace P_ ((int, int, int, int, int, int));
44 static void adjust_point P_ ((int, int));
46 Lisp_Object Fcombine_after_change_execute ();
48 /* Non-nil means don't call the after-change-functions right away,
49 just record an element in Vcombine_after_change_calls_list. */
50 Lisp_Object Vcombine_after_change_calls;
52 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
53 describing changes which happened while combine_after_change_calls
54 was nonzero. We use this to decide how to call them
55 once the deferral ends.
57 In each element.
58 BEG-UNCHANGED is the number of chars before the changed range.
59 END-UNCHANGED is the number of chars after the changed range,
60 and CHANGE-AMOUNT is the number of characters inserted by the change
61 (negative for a deletion). */
62 Lisp_Object combine_after_change_list;
64 /* Buffer which combine_after_change_list is about. */
65 Lisp_Object combine_after_change_buffer;
67 Lisp_Object Qinhibit_modification_hooks;
70 /* Check all markers in the current buffer, looking for something invalid. */
72 static int check_markers_debug_flag;
74 #define CHECK_MARKERS() \
75 if (check_markers_debug_flag) \
76 check_markers (); \
77 else
79 void
80 check_markers ()
82 register struct Lisp_Marker *tail;
83 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
85 for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
87 if (tail->buffer->text != current_buffer->text)
88 abort ();
89 if (tail->charpos > Z)
90 abort ();
91 if (tail->bytepos > Z_BYTE)
92 abort ();
93 if (multibyte && ! CHAR_HEAD_P (FETCH_BYTE (tail->bytepos)))
94 abort ();
98 /* Move gap to position CHARPOS.
99 Note that this can quit! */
101 void
102 move_gap (charpos)
103 int charpos;
105 move_gap_both (charpos, charpos_to_bytepos (charpos));
108 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
109 Note that this can quit! */
111 void
112 move_gap_both (charpos, bytepos)
113 int charpos, bytepos;
115 if (bytepos < GPT_BYTE)
116 gap_left (charpos, bytepos, 0);
117 else if (bytepos > GPT_BYTE)
118 gap_right (charpos, bytepos);
121 /* Move the gap to a position less than the current GPT.
122 BYTEPOS describes the new position as a byte position,
123 and CHARPOS is the corresponding char position.
124 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
126 static void
127 gap_left (charpos, bytepos, newgap)
128 register int charpos, bytepos;
129 int newgap;
131 register unsigned char *to, *from;
132 register int i;
133 int new_s1;
135 if (!newgap)
136 BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
138 i = GPT_BYTE;
139 to = GAP_END_ADDR;
140 from = GPT_ADDR;
141 new_s1 = GPT_BYTE;
143 /* Now copy the characters. To move the gap down,
144 copy characters up. */
146 while (1)
148 /* I gets number of characters left to copy. */
149 i = new_s1 - bytepos;
150 if (i == 0)
151 break;
152 /* If a quit is requested, stop copying now.
153 Change BYTEPOS to be where we have actually moved the gap to. */
154 if (QUITP)
156 bytepos = new_s1;
157 charpos = BYTE_TO_CHAR (bytepos);
158 break;
160 /* Move at most 32000 chars before checking again for a quit. */
161 if (i > 32000)
162 i = 32000;
163 #ifdef GAP_USE_BCOPY
164 if (i >= 128
165 /* bcopy is safe if the two areas of memory do not overlap
166 or on systems where bcopy is always safe for moving upward. */
167 && (BCOPY_UPWARD_SAFE
168 || to - from >= 128))
170 /* If overlap is not safe, avoid it by not moving too many
171 characters at once. */
172 if (!BCOPY_UPWARD_SAFE && i > to - from)
173 i = to - from;
174 new_s1 -= i;
175 from -= i, to -= i;
176 bcopy (from, to, i);
178 else
179 #endif
181 new_s1 -= i;
182 while (--i >= 0)
183 *--to = *--from;
187 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
188 BYTEPOS is where the loop above stopped, which may be what was specified
189 or may be where a quit was detected. */
190 adjust_markers_gap_motion (bytepos, GPT_BYTE, GAP_SIZE);
191 GPT_BYTE = bytepos;
192 GPT = charpos;
193 if (bytepos < charpos)
194 abort ();
195 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
196 QUIT;
199 /* Move the gap to a position greater than than the current GPT.
200 BYTEPOS describes the new position as a byte position,
201 and CHARPOS is the corresponding char position. */
203 static void
204 gap_right (charpos, bytepos)
205 register int charpos, bytepos;
207 register unsigned char *to, *from;
208 register int i;
209 int new_s1;
211 BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
213 i = GPT_BYTE;
214 from = GAP_END_ADDR;
215 to = GPT_ADDR;
216 new_s1 = GPT_BYTE;
218 /* Now copy the characters. To move the gap up,
219 copy characters down. */
221 while (1)
223 /* I gets number of characters left to copy. */
224 i = bytepos - new_s1;
225 if (i == 0)
226 break;
227 /* If a quit is requested, stop copying now.
228 Change BYTEPOS to be where we have actually moved the gap to. */
229 if (QUITP)
231 bytepos = new_s1;
232 charpos = BYTE_TO_CHAR (bytepos);
233 break;
235 /* Move at most 32000 chars before checking again for a quit. */
236 if (i > 32000)
237 i = 32000;
238 #ifdef GAP_USE_BCOPY
239 if (i >= 128
240 /* bcopy is safe if the two areas of memory do not overlap
241 or on systems where bcopy is always safe for moving downward. */
242 && (BCOPY_DOWNWARD_SAFE
243 || from - to >= 128))
245 /* If overlap is not safe, avoid it by not moving too many
246 characters at once. */
247 if (!BCOPY_DOWNWARD_SAFE && i > from - to)
248 i = from - to;
249 new_s1 += i;
250 bcopy (from, to, i);
251 from += i, to += i;
253 else
254 #endif
256 new_s1 += i;
257 while (--i >= 0)
258 *to++ = *from++;
262 adjust_markers_gap_motion (GPT_BYTE + GAP_SIZE, bytepos + GAP_SIZE,
263 - GAP_SIZE);
264 GPT = charpos;
265 GPT_BYTE = bytepos;
266 if (bytepos < charpos)
267 abort ();
268 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
269 QUIT;
272 /* Add AMOUNT to the byte position of every marker in the current buffer
273 whose current byte position is between FROM (exclusive) and TO (inclusive).
275 Also, any markers past the outside of that interval, in the direction
276 of adjustment, are first moved back to the near end of the interval
277 and then adjusted by AMOUNT.
279 When the latter adjustment is done, if AMOUNT is negative,
280 we record the adjustment for undo. (This case happens only for
281 deletion.)
283 The markers' character positions are not altered,
284 because gap motion does not affect character positions. */
286 int adjust_markers_test;
288 static void
289 adjust_markers_gap_motion (from, to, amount)
290 register int from, to, amount;
292 /* Now that a marker has a bytepos, not counting the gap,
293 nothing needs to be done here. */
294 #if 0
295 Lisp_Object marker;
296 register struct Lisp_Marker *m;
297 register int mpos;
299 marker = BUF_MARKERS (current_buffer);
301 while (!NILP (marker))
303 m = XMARKER (marker);
304 mpos = m->bytepos;
305 if (amount > 0)
307 if (mpos > to && mpos < to + amount)
309 if (adjust_markers_test)
310 abort ();
311 mpos = to + amount;
314 else
316 /* Here's the case where a marker is inside text being deleted.
317 AMOUNT can be negative for gap motion, too,
318 but then this range contains no markers. */
319 if (mpos > from + amount && mpos <= from)
321 if (adjust_markers_test)
322 abort ();
323 mpos = from + amount;
326 if (mpos > from && mpos <= to)
327 mpos += amount;
328 m->bufpos = mpos;
329 marker = m->chain;
331 #endif
334 /* Adjust all markers for a deletion
335 whose range in bytes is FROM_BYTE to TO_BYTE.
336 The range in charpos is FROM to TO.
338 This function assumes that the gap is adjacent to
339 or inside of the range being deleted. */
341 void
342 adjust_markers_for_delete (from, from_byte, to, to_byte)
343 register int from, from_byte, to, to_byte;
345 Lisp_Object marker;
346 register struct Lisp_Marker *m;
347 register int charpos;
349 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
351 charpos = m->charpos;
353 if (charpos > Z)
354 abort ();
356 /* If the marker is after the deletion,
357 relocate by number of chars / bytes deleted. */
358 if (charpos > to)
360 m->charpos -= to - from;
361 m->bytepos -= to_byte - from_byte;
363 /* Here's the case where a marker is inside text being deleted. */
364 else if (charpos > from)
366 if (! m->insertion_type)
367 { /* Normal markers will end up at the beginning of the
368 re-inserted text after undoing a deletion, and must be
369 adjusted to move them to the correct place. */
370 XSETMISC (marker, m);
371 record_marker_adjustment (marker, from - charpos);
373 else if (charpos < to)
374 { /* Before-insertion markers will automatically move forward
375 upon re-inserting the deleted text, so we have to arrange
376 for them to move backward to the correct position. */
377 XSETMISC (marker, m);
378 record_marker_adjustment (marker, charpos - to);
380 m->charpos = from;
381 m->bytepos = from_byte;
383 /* Here's the case where a before-insertion marker is immediately
384 before the deleted region. */
385 else if (charpos == from && m->insertion_type)
387 /* Undoing the change uses normal insertion, which will
388 incorrectly make MARKER move forward, so we arrange for it
389 to then move backward to the correct place at the beginning
390 of the deleted region. */
391 XSETMISC (marker, m);
392 record_marker_adjustment (marker, to - from);
398 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
399 to TO / TO_BYTE. We have to relocate the charpos of every marker
400 that points after the insertion (but not their bytepos).
402 When a marker points at the insertion point,
403 we advance it if either its insertion-type is t
404 or BEFORE_MARKERS is true. */
406 static void
407 adjust_markers_for_insert (from, from_byte, to, to_byte, before_markers)
408 register int from, from_byte, to, to_byte;
409 int before_markers;
411 struct Lisp_Marker *m;
412 int adjusted = 0;
413 int nchars = to - from;
414 int nbytes = to_byte - from_byte;
416 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
418 eassert (m->bytepos >= m->charpos
419 && m->bytepos - m->charpos <= Z_BYTE - Z);
421 if (m->bytepos == from_byte)
423 if (m->insertion_type || before_markers)
425 m->bytepos = to_byte;
426 m->charpos = to;
427 if (m->insertion_type)
428 adjusted = 1;
431 else if (m->bytepos > from_byte)
433 m->bytepos += nbytes;
434 m->charpos += nchars;
438 /* Adjusting only markers whose insertion-type is t may result in
439 - disordered start and end in overlays, and
440 - disordered overlays in the slot `overlays_before' of current_buffer. */
441 if (adjusted)
443 fix_start_end_in_overlays(from, to);
444 fix_overlays_before (current_buffer, from, to);
448 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
450 This is used only when the value of point changes due to an insert
451 or delete; it does not represent a conceptual change in point as a
452 marker. In particular, point is not crossing any interval
453 boundaries, so there's no need to use the usual SET_PT macro. In
454 fact it would be incorrect to do so, because either the old or the
455 new value of point is out of sync with the current set of
456 intervals. */
458 static void
459 adjust_point (nchars, nbytes)
460 int nchars, nbytes;
462 BUF_PT (current_buffer) += nchars;
463 BUF_PT_BYTE (current_buffer) += nbytes;
465 /* In a single-byte buffer, the two positions must be equal. */
466 eassert (PT_BYTE >= PT && PT_BYTE - PT <= ZV_BYTE - ZV);
469 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
470 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
471 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
472 an insertion. */
474 static void
475 adjust_markers_for_replace (from, from_byte, old_chars, old_bytes,
476 new_chars, new_bytes)
477 int from, from_byte, old_chars, old_bytes, new_chars, new_bytes;
479 register struct Lisp_Marker *m;
480 int prev_to_byte = from_byte + old_bytes;
481 int diff_chars = new_chars - old_chars;
482 int diff_bytes = new_bytes - old_bytes;
484 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
486 if (m->bytepos >= prev_to_byte)
488 m->charpos += diff_chars;
489 m->bytepos += diff_bytes;
491 else if (m->bytepos > from_byte)
493 m->charpos = from;
494 m->bytepos = from_byte;
498 CHECK_MARKERS ();
502 /* Make the gap NBYTES_ADDED bytes longer. */
504 void
505 make_gap_larger (nbytes_added)
506 int nbytes_added;
508 Lisp_Object tem;
509 int real_gap_loc;
510 int real_gap_loc_byte;
511 int old_gap_size;
513 /* If we have to get more space, get enough to last a while. */
514 nbytes_added += 2000;
516 /* Don't allow a buffer size that won't fit in an int
517 even if it will fit in a Lisp integer.
518 That won't work because so many places use `int'.
520 Make sure we don't introduce overflows in the calculation. */
522 if (Z_BYTE - BEG_BYTE + GAP_SIZE
523 >= (((EMACS_INT) 1 << (min (VALBITS, BITS_PER_INT) - 1)) - 1
524 - nbytes_added))
525 error ("Buffer exceeds maximum size");
527 enlarge_buffer_text (current_buffer, nbytes_added);
529 /* Prevent quitting in move_gap. */
530 tem = Vinhibit_quit;
531 Vinhibit_quit = Qt;
533 real_gap_loc = GPT;
534 real_gap_loc_byte = GPT_BYTE;
535 old_gap_size = GAP_SIZE;
537 /* Call the newly allocated space a gap at the end of the whole space. */
538 GPT = Z + GAP_SIZE;
539 GPT_BYTE = Z_BYTE + GAP_SIZE;
540 GAP_SIZE = nbytes_added;
542 /* Move the new gap down to be consecutive with the end of the old one.
543 This adjusts the markers properly too. */
544 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
546 /* Now combine the two into one large gap. */
547 GAP_SIZE += old_gap_size;
548 GPT = real_gap_loc;
549 GPT_BYTE = real_gap_loc_byte;
551 /* Put an anchor. */
552 *(Z_ADDR) = 0;
554 Vinhibit_quit = tem;
558 /* Make the gap NBYTES_REMOVED bytes shorter. */
560 void
561 make_gap_smaller (nbytes_removed)
562 int nbytes_removed;
564 Lisp_Object tem;
565 int real_gap_loc;
566 int real_gap_loc_byte;
567 int real_Z;
568 int real_Z_byte;
569 int real_beg_unchanged;
570 int new_gap_size;
572 /* Make sure the gap is at least 20 bytes. */
573 if (GAP_SIZE - nbytes_removed < 20)
574 nbytes_removed = GAP_SIZE - 20;
576 /* Prevent quitting in move_gap. */
577 tem = Vinhibit_quit;
578 Vinhibit_quit = Qt;
580 real_gap_loc = GPT;
581 real_gap_loc_byte = GPT_BYTE;
582 new_gap_size = GAP_SIZE - nbytes_removed;
583 real_Z = Z;
584 real_Z_byte = Z_BYTE;
585 real_beg_unchanged = BEG_UNCHANGED;
587 /* Pretend that the last unwanted part of the gap is the entire gap,
588 and that the first desired part of the gap is part of the buffer
589 text. */
590 bzero (GPT_ADDR, new_gap_size);
591 GPT += new_gap_size;
592 GPT_BYTE += new_gap_size;
593 Z += new_gap_size;
594 Z_BYTE += new_gap_size;
595 GAP_SIZE = nbytes_removed;
597 /* Move the unwanted pretend gap to the end of the buffer. This
598 adjusts the markers properly too. */
599 gap_right (Z, Z_BYTE);
601 enlarge_buffer_text (current_buffer, -nbytes_removed);
603 /* Now restore the desired gap. */
604 GAP_SIZE = new_gap_size;
605 GPT = real_gap_loc;
606 GPT_BYTE = real_gap_loc_byte;
607 Z = real_Z;
608 Z_BYTE = real_Z_byte;
609 BEG_UNCHANGED = real_beg_unchanged;
611 /* Put an anchor. */
612 *(Z_ADDR) = 0;
614 Vinhibit_quit = tem;
617 void
618 make_gap (nbytes_added)
619 int nbytes_added;
621 if (nbytes_added >= 0)
622 make_gap_larger (nbytes_added);
623 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
624 else
625 make_gap_smaller (-nbytes_added);
626 #endif
629 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
630 FROM_MULTIBYTE says whether the incoming text is multibyte.
631 TO_MULTIBYTE says whether to store the text as multibyte.
632 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
634 Return the number of bytes stored at TO_ADDR. */
637 copy_text (from_addr, to_addr, nbytes,
638 from_multibyte, to_multibyte)
639 const unsigned char *from_addr;
640 unsigned char *to_addr;
641 int nbytes;
642 int from_multibyte, to_multibyte;
644 if (from_multibyte == to_multibyte)
646 bcopy (from_addr, to_addr, nbytes);
647 return nbytes;
649 else if (from_multibyte)
651 int nchars = 0;
652 int bytes_left = nbytes;
653 Lisp_Object tbl = Qnil;
655 while (bytes_left > 0)
657 int thislen, c;
658 c = STRING_CHAR_AND_LENGTH (from_addr, bytes_left, thislen);
659 if (!ASCII_CHAR_P (c))
660 c = multibyte_char_to_unibyte (c, tbl);
661 *to_addr++ = c;
662 from_addr += thislen;
663 bytes_left -= thislen;
664 nchars++;
666 return nchars;
668 else
670 unsigned char *initial_to_addr = to_addr;
672 /* Convert single-byte to multibyte. */
673 while (nbytes > 0)
675 int c = *from_addr++;
677 if (c >= 0200)
679 c = unibyte_char_to_multibyte (c);
680 to_addr += CHAR_STRING (c, to_addr);
681 nbytes--;
683 else
684 /* Special case for speed. */
685 *to_addr++ = c, nbytes--;
687 return to_addr - initial_to_addr;
691 /* Return the number of bytes it would take
692 to convert some single-byte text to multibyte.
693 The single-byte text consists of NBYTES bytes at PTR. */
696 count_size_as_multibyte (ptr, nbytes)
697 const unsigned char *ptr;
698 int nbytes;
700 int i;
701 int outgoing_nbytes = 0;
703 for (i = 0; i < nbytes; i++)
705 unsigned int c = *ptr++;
707 if (c < 0200)
708 outgoing_nbytes++;
709 else
711 c = unibyte_char_to_multibyte (c);
712 outgoing_nbytes += CHAR_BYTES (c);
716 return outgoing_nbytes;
719 /* Insert a string of specified length before point.
720 This function judges multibyteness based on
721 enable_multibyte_characters in the current buffer;
722 it never converts between single-byte and multibyte.
724 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
725 prepare_to_modify_buffer could relocate the text. */
727 void
728 insert (string, nbytes)
729 register const unsigned char *string;
730 register int nbytes;
732 if (nbytes > 0)
734 int len = chars_in_text (string, nbytes), opoint;
735 insert_1_both (string, len, nbytes, 0, 1, 0);
736 opoint = PT - len;
737 signal_after_change (opoint, 0, len);
738 update_compositions (opoint, PT, CHECK_BORDER);
742 /* Likewise, but inherit text properties from neighboring characters. */
744 void
745 insert_and_inherit (string, nbytes)
746 register const unsigned char *string;
747 register int nbytes;
749 if (nbytes > 0)
751 int len = chars_in_text (string, nbytes), opoint;
752 insert_1_both (string, len, nbytes, 1, 1, 0);
753 opoint = PT - len;
754 signal_after_change (opoint, 0, len);
755 update_compositions (opoint, PT, CHECK_BORDER);
759 /* Insert the character C before point. Do not inherit text properties. */
761 void
762 insert_char (c)
763 int c;
765 unsigned char str[MAX_MULTIBYTE_LENGTH];
766 int len;
768 if (! NILP (current_buffer->enable_multibyte_characters))
769 len = CHAR_STRING (c, str);
770 else
772 len = 1;
773 str[0] = c;
776 insert (str, len);
779 /* Insert the null-terminated string S before point. */
781 void
782 insert_string (s)
783 const char *s;
785 insert (s, strlen (s));
788 /* Like `insert' except that all markers pointing at the place where
789 the insertion happens are adjusted to point after it.
790 Don't use this function to insert part of a Lisp string,
791 since gc could happen and relocate it. */
793 void
794 insert_before_markers (string, nbytes)
795 const unsigned char *string;
796 register int nbytes;
798 if (nbytes > 0)
800 int len = chars_in_text (string, nbytes), opoint;
801 insert_1_both (string, len, nbytes, 0, 1, 1);
802 opoint = PT - len;
803 signal_after_change (opoint, 0, len);
804 update_compositions (opoint, PT, CHECK_BORDER);
808 /* Likewise, but inherit text properties from neighboring characters. */
810 void
811 insert_before_markers_and_inherit (string, nbytes)
812 const unsigned char *string;
813 register int nbytes;
815 if (nbytes > 0)
817 int len = chars_in_text (string, nbytes), opoint;
818 insert_1_both (string, len, nbytes, 1, 1, 1);
819 opoint = PT - len;
820 signal_after_change (opoint, 0, len);
821 update_compositions (opoint, PT, CHECK_BORDER);
825 /* Subroutine used by the insert functions above. */
827 void
828 insert_1 (string, nbytes, inherit, prepare, before_markers)
829 register const unsigned char *string;
830 register int nbytes;
831 int inherit, prepare, before_markers;
833 insert_1_both (string, chars_in_text (string, nbytes), nbytes,
834 inherit, prepare, before_markers);
838 #ifdef BYTE_COMBINING_DEBUG
840 /* See if the bytes before POS/POS_BYTE combine with bytes
841 at the start of STRING to form a single character.
842 If so, return the number of bytes at the start of STRING
843 which combine in this way. Otherwise, return 0. */
846 count_combining_before (string, length, pos, pos_byte)
847 const unsigned char *string;
848 int length;
849 int pos, pos_byte;
851 int len, combining_bytes;
852 const unsigned char *p;
854 if (NILP (current_buffer->enable_multibyte_characters))
855 return 0;
857 /* At first, we can exclude the following cases:
858 (1) STRING[0] can't be a following byte of multibyte sequence.
859 (2) POS is the start of the current buffer.
860 (3) A character before POS is not a multibyte character. */
861 if (length == 0 || CHAR_HEAD_P (*string)) /* case (1) */
862 return 0;
863 if (pos_byte == BEG_BYTE) /* case (2) */
864 return 0;
865 len = 1;
866 p = BYTE_POS_ADDR (pos_byte - 1);
867 while (! CHAR_HEAD_P (*p)) p--, len++;
868 if (! BASE_LEADING_CODE_P (*p)) /* case (3) */
869 return 0;
871 combining_bytes = BYTES_BY_CHAR_HEAD (*p) - len;
872 if (combining_bytes <= 0)
873 /* The character preceding POS is, complete and no room for
874 combining bytes (combining_bytes == 0), or an independent 8-bit
875 character (combining_bytes < 0). */
876 return 0;
878 /* We have a combination situation. Count the bytes at STRING that
879 may combine. */
880 p = string + 1;
881 while (!CHAR_HEAD_P (*p) && p < string + length)
882 p++;
884 return (combining_bytes < p - string ? combining_bytes : p - string);
887 /* See if the bytes after POS/POS_BYTE combine with bytes
888 at the end of STRING to form a single character.
889 If so, return the number of bytes after POS/POS_BYTE
890 which combine in this way. Otherwise, return 0. */
893 count_combining_after (string, length, pos, pos_byte)
894 const unsigned char *string;
895 int length;
896 int pos, pos_byte;
898 int opos_byte = pos_byte;
899 int i;
900 int bytes;
901 unsigned char *bufp;
903 if (NILP (current_buffer->enable_multibyte_characters))
904 return 0;
906 /* At first, we can exclude the following cases:
907 (1) The last byte of STRING is an ASCII.
908 (2) POS is the last of the current buffer.
909 (3) A character at POS can't be a following byte of multibyte
910 character. */
911 if (length > 0 && ASCII_BYTE_P (string[length - 1])) /* case (1) */
912 return 0;
913 if (pos_byte == Z_BYTE) /* case (2) */
914 return 0;
915 bufp = BYTE_POS_ADDR (pos_byte);
916 if (CHAR_HEAD_P (*bufp)) /* case (3) */
917 return 0;
919 i = length - 1;
920 while (i >= 0 && ! CHAR_HEAD_P (string[i]))
922 i--;
924 if (i < 0)
926 /* All characters in STRING are not character head. We must
927 check also preceding bytes at POS. We are sure that the gap
928 is at POS. */
929 unsigned char *p = BEG_ADDR;
930 i = pos_byte - 2;
931 while (i >= 0 && ! CHAR_HEAD_P (p[i]))
932 i--;
933 if (i < 0 || !BASE_LEADING_CODE_P (p[i]))
934 return 0;
936 bytes = BYTES_BY_CHAR_HEAD (p[i]);
937 return (bytes <= pos_byte - 1 - i + length
939 : bytes - (pos_byte - 1 - i + length));
941 if (!BASE_LEADING_CODE_P (string[i]))
942 return 0;
944 bytes = BYTES_BY_CHAR_HEAD (string[i]) - (length - i);
945 bufp++, pos_byte++;
946 while (!CHAR_HEAD_P (*bufp)) bufp++, pos_byte++;
948 return (bytes <= pos_byte - opos_byte ? bytes : pos_byte - opos_byte);
951 #endif
954 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
955 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
956 are the same as in insert_1. */
958 void
959 insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers)
960 register const unsigned char *string;
961 register int nchars, nbytes;
962 int inherit, prepare, before_markers;
964 if (nchars == 0)
965 return;
967 if (NILP (current_buffer->enable_multibyte_characters))
968 nchars = nbytes;
970 if (prepare)
971 /* Do this before moving and increasing the gap,
972 because the before-change hooks might move the gap
973 or make it smaller. */
974 prepare_to_modify_buffer (PT, PT, NULL);
976 if (PT != GPT)
977 move_gap_both (PT, PT_BYTE);
978 if (GAP_SIZE < nbytes)
979 make_gap (nbytes - GAP_SIZE);
981 #ifdef BYTE_COMBINING_DEBUG
982 if (count_combining_before (string, nbytes, PT, PT_BYTE)
983 || count_combining_after (string, nbytes, PT, PT_BYTE))
984 abort ();
985 #endif
987 /* Record deletion of the surrounding text that combines with
988 the insertion. This, together with recording the insertion,
989 will add up to the right stuff in the undo list. */
990 record_insert (PT, nchars);
991 MODIFF++;
992 CHARS_MODIFF = MODIFF;
994 bcopy (string, GPT_ADDR, nbytes);
996 GAP_SIZE -= nbytes;
997 GPT += nchars;
998 ZV += nchars;
999 Z += nchars;
1000 GPT_BYTE += nbytes;
1001 ZV_BYTE += nbytes;
1002 Z_BYTE += nbytes;
1003 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1005 if (GPT_BYTE < GPT)
1006 abort ();
1008 /* The insert may have been in the unchanged region, so check again. */
1009 if (Z - GPT < END_UNCHANGED)
1010 END_UNCHANGED = Z - GPT;
1012 adjust_overlays_for_insert (PT, nchars);
1013 adjust_markers_for_insert (PT, PT_BYTE,
1014 PT + nchars, PT_BYTE + nbytes,
1015 before_markers);
1017 if (BUF_INTERVALS (current_buffer) != 0)
1018 offset_intervals (current_buffer, PT, nchars);
1020 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
1021 set_text_properties (make_number (PT), make_number (PT + nchars),
1022 Qnil, Qnil, Qnil);
1024 adjust_point (nchars, nbytes);
1026 CHECK_MARKERS ();
1029 /* Insert the part of the text of STRING, a Lisp object assumed to be
1030 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1031 starting at position POS / POS_BYTE. If the text of STRING has properties,
1032 copy them into the buffer.
1034 It does not work to use `insert' for this, because a GC could happen
1035 before we bcopy the stuff into the buffer, and relocate the string
1036 without insert noticing. */
1038 void
1039 insert_from_string (string, pos, pos_byte, length, length_byte, inherit)
1040 Lisp_Object string;
1041 register int pos, pos_byte, length, length_byte;
1042 int inherit;
1044 int opoint = PT;
1046 if (SCHARS (string) == 0)
1047 return;
1049 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1050 inherit, 0);
1051 signal_after_change (opoint, 0, PT - opoint);
1052 update_compositions (opoint, PT, CHECK_BORDER);
1055 /* Like `insert_from_string' except that all markers pointing
1056 at the place where the insertion happens are adjusted to point after it. */
1058 void
1059 insert_from_string_before_markers (string, pos, pos_byte,
1060 length, length_byte, inherit)
1061 Lisp_Object string;
1062 register int pos, pos_byte, length, length_byte;
1063 int inherit;
1065 int opoint = PT;
1067 if (SCHARS (string) == 0)
1068 return;
1070 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1071 inherit, 1);
1072 signal_after_change (opoint, 0, PT - opoint);
1073 update_compositions (opoint, PT, CHECK_BORDER);
1076 /* Subroutine of the insertion functions above. */
1078 static void
1079 insert_from_string_1 (string, pos, pos_byte, nchars, nbytes,
1080 inherit, before_markers)
1081 Lisp_Object string;
1082 register int pos, pos_byte, nchars, nbytes;
1083 int inherit, before_markers;
1085 struct gcpro gcpro1;
1086 int outgoing_nbytes = nbytes;
1087 INTERVAL intervals;
1089 /* Make OUTGOING_NBYTES describe the text
1090 as it will be inserted in this buffer. */
1092 if (NILP (current_buffer->enable_multibyte_characters))
1093 outgoing_nbytes = nchars;
1094 else if (! STRING_MULTIBYTE (string))
1095 outgoing_nbytes
1096 = count_size_as_multibyte (SDATA (string) + pos_byte,
1097 nbytes);
1099 GCPRO1 (string);
1100 /* Do this before moving and increasing the gap,
1101 because the before-change hooks might move the gap
1102 or make it smaller. */
1103 prepare_to_modify_buffer (PT, PT, NULL);
1105 if (PT != GPT)
1106 move_gap_both (PT, PT_BYTE);
1107 if (GAP_SIZE < outgoing_nbytes)
1108 make_gap (outgoing_nbytes - GAP_SIZE);
1109 UNGCPRO;
1111 /* Copy the string text into the buffer, perhaps converting
1112 between single-byte and multibyte. */
1113 copy_text (SDATA (string) + pos_byte, GPT_ADDR, nbytes,
1114 STRING_MULTIBYTE (string),
1115 ! NILP (current_buffer->enable_multibyte_characters));
1117 #ifdef BYTE_COMBINING_DEBUG
1118 /* We have copied text into the gap, but we have not altered
1119 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1120 to these functions and get the same results as we would
1121 have got earlier on. Meanwhile, PT_ADDR does point to
1122 the text that has been stored by copy_text. */
1123 if (count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE)
1124 || count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE))
1125 abort ();
1126 #endif
1128 record_insert (PT, nchars);
1129 MODIFF++;
1130 CHARS_MODIFF = MODIFF;
1132 GAP_SIZE -= outgoing_nbytes;
1133 GPT += nchars;
1134 ZV += nchars;
1135 Z += nchars;
1136 GPT_BYTE += outgoing_nbytes;
1137 ZV_BYTE += outgoing_nbytes;
1138 Z_BYTE += outgoing_nbytes;
1139 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1141 if (GPT_BYTE < GPT)
1142 abort ();
1144 /* The insert may have been in the unchanged region, so check again. */
1145 if (Z - GPT < END_UNCHANGED)
1146 END_UNCHANGED = Z - GPT;
1148 adjust_overlays_for_insert (PT, nchars);
1149 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1150 PT_BYTE + outgoing_nbytes,
1151 before_markers);
1153 offset_intervals (current_buffer, PT, nchars);
1155 intervals = STRING_INTERVALS (string);
1156 /* Get the intervals for the part of the string we are inserting. */
1157 if (nbytes < SBYTES (string))
1158 intervals = copy_intervals (intervals, pos, nchars);
1160 /* Insert those intervals. */
1161 graft_intervals_into_buffer (intervals, PT, nchars,
1162 current_buffer, inherit);
1164 adjust_point (nchars, outgoing_nbytes);
1166 CHECK_MARKERS ();
1169 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1170 starting at GPT_ADDR. */
1172 void
1173 insert_from_gap (nchars, nbytes)
1174 register int nchars, nbytes;
1176 if (NILP (current_buffer->enable_multibyte_characters))
1177 nchars = nbytes;
1179 record_insert (GPT, nchars);
1180 MODIFF++;
1182 GAP_SIZE -= nbytes;
1183 GPT += nchars;
1184 ZV += nchars;
1185 Z += nchars;
1186 GPT_BYTE += nbytes;
1187 ZV_BYTE += nbytes;
1188 Z_BYTE += nbytes;
1189 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1191 if (GPT_BYTE < GPT)
1192 abort ();
1194 adjust_overlays_for_insert (GPT - nchars, nchars);
1195 adjust_markers_for_insert (GPT - nchars, GPT_BYTE - nbytes,
1196 GPT, GPT_BYTE, 0);
1198 if (BUF_INTERVALS (current_buffer) != 0)
1200 offset_intervals (current_buffer, GPT - nchars, nchars);
1201 graft_intervals_into_buffer (NULL_INTERVAL, GPT - nchars, nchars,
1202 current_buffer, 0);
1205 if (GPT - nchars < PT)
1206 adjust_point (nchars, nbytes);
1208 CHECK_MARKERS ();
1211 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1212 current buffer. If the text in BUF has properties, they are absorbed
1213 into the current buffer.
1215 It does not work to use `insert' for this, because a malloc could happen
1216 and relocate BUF's text before the bcopy happens. */
1218 void
1219 insert_from_buffer (buf, charpos, nchars, inherit)
1220 struct buffer *buf;
1221 int charpos, nchars;
1222 int inherit;
1224 int opoint = PT;
1226 insert_from_buffer_1 (buf, charpos, nchars, inherit);
1227 signal_after_change (opoint, 0, PT - opoint);
1228 update_compositions (opoint, PT, CHECK_BORDER);
1231 static void
1232 insert_from_buffer_1 (buf, from, nchars, inherit)
1233 struct buffer *buf;
1234 int from, nchars;
1235 int inherit;
1237 register Lisp_Object temp;
1238 int chunk, chunk_expanded;
1239 int from_byte = buf_charpos_to_bytepos (buf, from);
1240 int to_byte = buf_charpos_to_bytepos (buf, from + nchars);
1241 int incoming_nbytes = to_byte - from_byte;
1242 int outgoing_nbytes = incoming_nbytes;
1243 INTERVAL intervals;
1245 /* Make OUTGOING_NBYTES describe the text
1246 as it will be inserted in this buffer. */
1248 if (NILP (current_buffer->enable_multibyte_characters))
1249 outgoing_nbytes = nchars;
1250 else if (NILP (buf->enable_multibyte_characters))
1252 int outgoing_before_gap = 0;
1253 int outgoing_after_gap = 0;
1255 if (from < BUF_GPT (buf))
1257 chunk = BUF_GPT_BYTE (buf) - from_byte;
1258 if (chunk > incoming_nbytes)
1259 chunk = incoming_nbytes;
1260 outgoing_before_gap
1261 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf, from_byte),
1262 chunk);
1264 else
1265 chunk = 0;
1267 if (chunk < incoming_nbytes)
1268 outgoing_after_gap
1269 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf,
1270 from_byte + chunk),
1271 incoming_nbytes - chunk);
1273 outgoing_nbytes = outgoing_before_gap + outgoing_after_gap;
1276 /* Make sure point-max won't overflow after this insertion. */
1277 XSETINT (temp, outgoing_nbytes + Z);
1278 if (outgoing_nbytes + Z != XINT (temp))
1279 error ("Maximum buffer size exceeded");
1281 /* Do this before moving and increasing the gap,
1282 because the before-change hooks might move the gap
1283 or make it smaller. */
1284 prepare_to_modify_buffer (PT, PT, NULL);
1286 if (PT != GPT)
1287 move_gap_both (PT, PT_BYTE);
1288 if (GAP_SIZE < outgoing_nbytes)
1289 make_gap (outgoing_nbytes - GAP_SIZE);
1291 if (from < BUF_GPT (buf))
1293 chunk = BUF_GPT_BYTE (buf) - from_byte;
1294 if (chunk > incoming_nbytes)
1295 chunk = incoming_nbytes;
1296 /* Record number of output bytes, so we know where
1297 to put the output from the second copy_text. */
1298 chunk_expanded
1299 = copy_text (BUF_BYTE_ADDRESS (buf, from_byte),
1300 GPT_ADDR, chunk,
1301 ! NILP (buf->enable_multibyte_characters),
1302 ! NILP (current_buffer->enable_multibyte_characters));
1304 else
1305 chunk_expanded = chunk = 0;
1307 if (chunk < incoming_nbytes)
1308 copy_text (BUF_BYTE_ADDRESS (buf, from_byte + chunk),
1309 GPT_ADDR + chunk_expanded, incoming_nbytes - chunk,
1310 ! NILP (buf->enable_multibyte_characters),
1311 ! NILP (current_buffer->enable_multibyte_characters));
1313 #ifdef BYTE_COMBINING_DEBUG
1314 /* We have copied text into the gap, but we have not altered
1315 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1316 to these functions and get the same results as we would
1317 have got earlier on. Meanwhile, GPT_ADDR does point to
1318 the text that has been stored by copy_text. */
1319 if (count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE)
1320 || count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE))
1321 abort ();
1322 #endif
1324 record_insert (PT, nchars);
1325 MODIFF++;
1326 CHARS_MODIFF = MODIFF;
1328 GAP_SIZE -= outgoing_nbytes;
1329 GPT += nchars;
1330 ZV += nchars;
1331 Z += nchars;
1332 GPT_BYTE += outgoing_nbytes;
1333 ZV_BYTE += outgoing_nbytes;
1334 Z_BYTE += outgoing_nbytes;
1335 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1337 if (GPT_BYTE < GPT)
1338 abort ();
1340 /* The insert may have been in the unchanged region, so check again. */
1341 if (Z - GPT < END_UNCHANGED)
1342 END_UNCHANGED = Z - GPT;
1344 adjust_overlays_for_insert (PT, nchars);
1345 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1346 PT_BYTE + outgoing_nbytes,
1349 if (BUF_INTERVALS (current_buffer) != 0)
1350 offset_intervals (current_buffer, PT, nchars);
1352 /* Get the intervals for the part of the string we are inserting. */
1353 intervals = BUF_INTERVALS (buf);
1354 if (outgoing_nbytes < BUF_Z_BYTE (buf) - BUF_BEG_BYTE (buf))
1356 if (buf == current_buffer && PT <= from)
1357 from += nchars;
1358 intervals = copy_intervals (intervals, from, nchars);
1361 /* Insert those intervals. */
1362 graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
1364 adjust_point (nchars, outgoing_nbytes);
1367 /* Record undo information and adjust markers and position keepers for
1368 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1369 chars (LEN_BYTE bytes) which resides in the gap just after
1370 GPT_ADDR.
1372 PREV_TEXT nil means the new text was just inserted. */
1374 void
1375 adjust_after_replace (from, from_byte, prev_text, len, len_byte)
1376 int from, from_byte, len, len_byte;
1377 Lisp_Object prev_text;
1379 int nchars_del = 0, nbytes_del = 0;
1381 #ifdef BYTE_COMBINING_DEBUG
1382 if (count_combining_before (GPT_ADDR, len_byte, from, from_byte)
1383 || count_combining_after (GPT_ADDR, len_byte, from, from_byte))
1384 abort ();
1385 #endif
1387 if (STRINGP (prev_text))
1389 nchars_del = SCHARS (prev_text);
1390 nbytes_del = SBYTES (prev_text);
1393 /* Update various buffer positions for the new text. */
1394 GAP_SIZE -= len_byte;
1395 ZV += len; Z+= len;
1396 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1397 GPT += len; GPT_BYTE += len_byte;
1398 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1400 if (nchars_del > 0)
1401 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1402 len, len_byte);
1403 else
1404 adjust_markers_for_insert (from, from_byte,
1405 from + len, from_byte + len_byte, 0);
1407 if (! EQ (current_buffer->undo_list, Qt))
1409 if (nchars_del > 0)
1410 record_delete (from, prev_text);
1411 record_insert (from, len);
1414 if (len > nchars_del)
1415 adjust_overlays_for_insert (from, len - nchars_del);
1416 else if (len < nchars_del)
1417 adjust_overlays_for_delete (from, nchars_del - len);
1418 if (BUF_INTERVALS (current_buffer) != 0)
1420 offset_intervals (current_buffer, from, len - nchars_del);
1423 if (from < PT)
1424 adjust_point (len - nchars_del, len_byte - nbytes_del);
1426 /* As byte combining will decrease Z, we must check this again. */
1427 if (Z - GPT < END_UNCHANGED)
1428 END_UNCHANGED = Z - GPT;
1430 CHECK_MARKERS ();
1432 if (len == 0)
1433 evaporate_overlays (from);
1434 MODIFF++;
1435 CHARS_MODIFF = MODIFF;
1438 /* Like adjust_after_replace, but doesn't require PREV_TEXT.
1439 This is for use when undo is not enabled in the current buffer. */
1441 void
1442 adjust_after_replace_noundo (from, from_byte, nchars_del, nbytes_del, len, len_byte)
1443 int from, from_byte, nchars_del, nbytes_del, len, len_byte;
1445 #ifdef BYTE_COMBINING_DEBUG
1446 if (count_combining_before (GPT_ADDR, len_byte, from, from_byte)
1447 || count_combining_after (GPT_ADDR, len_byte, from, from_byte))
1448 abort ();
1449 #endif
1451 /* Update various buffer positions for the new text. */
1452 GAP_SIZE -= len_byte;
1453 ZV += len; Z+= len;
1454 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1455 GPT += len; GPT_BYTE += len_byte;
1456 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1458 if (nchars_del > 0)
1459 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1460 len, len_byte);
1461 else
1462 adjust_markers_for_insert (from, from_byte,
1463 from + len, from_byte + len_byte, 0);
1465 if (len > nchars_del)
1466 adjust_overlays_for_insert (from, len - nchars_del);
1467 else if (len < nchars_del)
1468 adjust_overlays_for_delete (from, nchars_del - len);
1469 if (BUF_INTERVALS (current_buffer) != 0)
1471 offset_intervals (current_buffer, from, len - nchars_del);
1474 if (from < PT)
1475 adjust_point (len - nchars_del, len_byte - nbytes_del);
1477 /* As byte combining will decrease Z, we must check this again. */
1478 if (Z - GPT < END_UNCHANGED)
1479 END_UNCHANGED = Z - GPT;
1481 CHECK_MARKERS ();
1483 if (len == 0)
1484 evaporate_overlays (from);
1485 MODIFF++;
1486 CHARS_MODIFF = MODIFF;
1489 /* Record undo information, adjust markers and position keepers for an
1490 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1491 text already exists in the current buffer but character length (TO
1492 - FROM) may be incorrect, the correct length is NEWLEN. */
1494 void
1495 adjust_after_insert (from, from_byte, to, to_byte, newlen)
1496 int from, from_byte, to, to_byte, newlen;
1498 int len = to - from, len_byte = to_byte - from_byte;
1500 if (GPT != to)
1501 move_gap_both (to, to_byte);
1502 GAP_SIZE += len_byte;
1503 GPT -= len; GPT_BYTE -= len_byte;
1504 ZV -= len; ZV_BYTE -= len_byte;
1505 Z -= len; Z_BYTE -= len_byte;
1506 adjust_after_replace (from, from_byte, Qnil, newlen, len_byte);
1509 /* Replace the text from character positions FROM to TO with NEW,
1510 If PREPARE is nonzero, call prepare_to_modify_buffer.
1511 If INHERIT, the newly inserted text should inherit text properties
1512 from the surrounding non-deleted text. */
1514 /* Note that this does not yet handle markers quite right.
1515 Also it needs to record a single undo-entry that does a replacement
1516 rather than a separate delete and insert.
1517 That way, undo will also handle markers properly.
1519 But if MARKERS is 0, don't relocate markers. */
1521 void
1522 replace_range (from, to, new, prepare, inherit, markers)
1523 Lisp_Object new;
1524 int from, to, prepare, inherit, markers;
1526 int inschars = SCHARS (new);
1527 int insbytes = SBYTES (new);
1528 int from_byte, to_byte;
1529 int nbytes_del, nchars_del;
1530 register Lisp_Object temp;
1531 struct gcpro gcpro1;
1532 INTERVAL intervals;
1533 int outgoing_insbytes = insbytes;
1534 Lisp_Object deletion;
1536 CHECK_MARKERS ();
1538 GCPRO1 (new);
1539 deletion = Qnil;
1541 if (prepare)
1543 int range_length = to - from;
1544 prepare_to_modify_buffer (from, to, &from);
1545 to = from + range_length;
1548 UNGCPRO;
1550 /* Make args be valid */
1551 if (from < BEGV)
1552 from = BEGV;
1553 if (to > ZV)
1554 to = ZV;
1556 from_byte = CHAR_TO_BYTE (from);
1557 to_byte = CHAR_TO_BYTE (to);
1559 nchars_del = to - from;
1560 nbytes_del = to_byte - from_byte;
1562 if (nbytes_del <= 0 && insbytes == 0)
1563 return;
1565 /* Make OUTGOING_INSBYTES describe the text
1566 as it will be inserted in this buffer. */
1568 if (NILP (current_buffer->enable_multibyte_characters))
1569 outgoing_insbytes = inschars;
1570 else if (! STRING_MULTIBYTE (new))
1571 outgoing_insbytes
1572 = count_size_as_multibyte (SDATA (new), insbytes);
1574 /* Make sure point-max won't overflow after this insertion. */
1575 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1576 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1577 error ("Maximum buffer size exceeded");
1579 GCPRO1 (new);
1581 /* Make sure the gap is somewhere in or next to what we are deleting. */
1582 if (from > GPT)
1583 gap_right (from, from_byte);
1584 if (to < GPT)
1585 gap_left (to, to_byte, 0);
1587 /* Even if we don't record for undo, we must keep the original text
1588 because we may have to recover it because of inappropriate byte
1589 combining. */
1590 if (! EQ (current_buffer->undo_list, Qt))
1591 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1593 GAP_SIZE += nbytes_del;
1594 ZV -= nchars_del;
1595 Z -= nchars_del;
1596 ZV_BYTE -= nbytes_del;
1597 Z_BYTE -= nbytes_del;
1598 GPT = from;
1599 GPT_BYTE = from_byte;
1600 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1602 if (GPT_BYTE < GPT)
1603 abort ();
1605 if (GPT - BEG < BEG_UNCHANGED)
1606 BEG_UNCHANGED = GPT - BEG;
1607 if (Z - GPT < END_UNCHANGED)
1608 END_UNCHANGED = Z - GPT;
1610 if (GAP_SIZE < insbytes)
1611 make_gap (insbytes - GAP_SIZE);
1613 /* Copy the string text into the buffer, perhaps converting
1614 between single-byte and multibyte. */
1615 copy_text (SDATA (new), GPT_ADDR, insbytes,
1616 STRING_MULTIBYTE (new),
1617 ! NILP (current_buffer->enable_multibyte_characters));
1619 #ifdef BYTE_COMBINING_DEBUG
1620 /* We have copied text into the gap, but we have not marked
1621 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1622 here, for both the previous text and the following text.
1623 Meanwhile, GPT_ADDR does point to
1624 the text that has been stored by copy_text. */
1625 if (count_combining_before (GPT_ADDR, outgoing_insbytes, from, from_byte)
1626 || count_combining_after (GPT_ADDR, outgoing_insbytes, from, from_byte))
1627 abort ();
1628 #endif
1630 if (! EQ (current_buffer->undo_list, Qt))
1632 /* Record the insertion first, so that when we undo,
1633 the deletion will be undone first. Thus, undo
1634 will insert before deleting, and thus will keep
1635 the markers before and after this text separate. */
1636 record_insert (from + SCHARS (deletion), inschars);
1637 record_delete (from, deletion);
1640 GAP_SIZE -= outgoing_insbytes;
1641 GPT += inschars;
1642 ZV += inschars;
1643 Z += inschars;
1644 GPT_BYTE += outgoing_insbytes;
1645 ZV_BYTE += outgoing_insbytes;
1646 Z_BYTE += outgoing_insbytes;
1647 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1649 if (GPT_BYTE < GPT)
1650 abort ();
1652 /* Adjust the overlay center as needed. This must be done after
1653 adjusting the markers that bound the overlays. */
1654 adjust_overlays_for_delete (from, nchars_del);
1655 adjust_overlays_for_insert (from, inschars);
1657 /* Adjust markers for the deletion and the insertion. */
1658 if (markers)
1659 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1660 inschars, outgoing_insbytes);
1662 offset_intervals (current_buffer, from, inschars - nchars_del);
1664 /* Get the intervals for the part of the string we are inserting--
1665 not including the combined-before bytes. */
1666 intervals = STRING_INTERVALS (new);
1667 /* Insert those intervals. */
1668 graft_intervals_into_buffer (intervals, from, inschars,
1669 current_buffer, inherit);
1671 /* Relocate point as if it were a marker. */
1672 if (from < PT)
1673 adjust_point ((from + inschars - (PT < to ? PT : to)),
1674 (from_byte + outgoing_insbytes
1675 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
1677 if (outgoing_insbytes == 0)
1678 evaporate_overlays (from);
1680 CHECK_MARKERS ();
1682 MODIFF++;
1683 CHARS_MODIFF = MODIFF;
1684 UNGCPRO;
1686 signal_after_change (from, nchars_del, GPT - from);
1687 update_compositions (from, GPT, CHECK_BORDER);
1690 /* Replace the text from character positions FROM to TO with
1691 the text in INS of length INSCHARS.
1692 Keep the text properties that applied to the old characters
1693 (extending them to all the new chars if there are more new chars).
1695 Note that this does not yet handle markers quite right.
1697 If MARKERS is nonzero, relocate markers.
1699 Unlike most functions at this level, never call
1700 prepare_to_modify_buffer and never call signal_after_change. */
1702 void
1703 replace_range_2 (from, from_byte, to, to_byte, ins, inschars, insbytes, markers)
1704 int from, from_byte, to, to_byte;
1705 char *ins;
1706 int inschars, insbytes, markers;
1708 int nbytes_del, nchars_del;
1709 Lisp_Object temp;
1711 CHECK_MARKERS ();
1713 nchars_del = to - from;
1714 nbytes_del = to_byte - from_byte;
1716 if (nbytes_del <= 0 && insbytes == 0)
1717 return;
1719 /* Make sure point-max won't overflow after this insertion. */
1720 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1721 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1722 error ("Maximum buffer size exceeded");
1724 /* Make sure the gap is somewhere in or next to what we are deleting. */
1725 if (from > GPT)
1726 gap_right (from, from_byte);
1727 if (to < GPT)
1728 gap_left (to, to_byte, 0);
1730 GAP_SIZE += nbytes_del;
1731 ZV -= nchars_del;
1732 Z -= nchars_del;
1733 ZV_BYTE -= nbytes_del;
1734 Z_BYTE -= nbytes_del;
1735 GPT = from;
1736 GPT_BYTE = from_byte;
1737 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1739 if (GPT_BYTE < GPT)
1740 abort ();
1742 if (GPT - BEG < BEG_UNCHANGED)
1743 BEG_UNCHANGED = GPT - BEG;
1744 if (Z - GPT < END_UNCHANGED)
1745 END_UNCHANGED = Z - GPT;
1747 if (GAP_SIZE < insbytes)
1748 make_gap (insbytes - GAP_SIZE);
1750 /* Copy the replacement text into the buffer. */
1751 bcopy (ins, GPT_ADDR, insbytes);
1753 #ifdef BYTE_COMBINING_DEBUG
1754 /* We have copied text into the gap, but we have not marked
1755 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1756 here, for both the previous text and the following text.
1757 Meanwhile, GPT_ADDR does point to
1758 the text that has been stored by copy_text. */
1759 if (count_combining_before (GPT_ADDR, insbytes, from, from_byte)
1760 || count_combining_after (GPT_ADDR, insbytes, from, from_byte))
1761 abort ();
1762 #endif
1764 GAP_SIZE -= insbytes;
1765 GPT += inschars;
1766 ZV += inschars;
1767 Z += inschars;
1768 GPT_BYTE += insbytes;
1769 ZV_BYTE += insbytes;
1770 Z_BYTE += insbytes;
1771 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1773 if (GPT_BYTE < GPT)
1774 abort ();
1776 /* Adjust the overlay center as needed. This must be done after
1777 adjusting the markers that bound the overlays. */
1778 if (nchars_del != inschars)
1780 adjust_overlays_for_insert (from, inschars);
1781 adjust_overlays_for_delete (from + inschars, nchars_del);
1784 /* Adjust markers for the deletion and the insertion. */
1785 if (markers
1786 && ! (nchars_del == 1 && inschars == 1 && nbytes_del == insbytes))
1787 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1788 inschars, insbytes);
1790 offset_intervals (current_buffer, from, inschars - nchars_del);
1792 /* Relocate point as if it were a marker. */
1793 if (from < PT && (nchars_del != inschars || nbytes_del != insbytes))
1795 if (PT < to)
1796 /* PT was within the deleted text. Move it to FROM. */
1797 adjust_point (from - PT, from_byte - PT_BYTE);
1798 else
1799 adjust_point (inschars - nchars_del, insbytes - nbytes_del);
1802 if (insbytes == 0)
1803 evaporate_overlays (from);
1805 CHECK_MARKERS ();
1807 MODIFF++;
1808 CHARS_MODIFF = MODIFF;
1811 /* Delete characters in current buffer
1812 from FROM up to (but not including) TO.
1813 If TO comes before FROM, we delete nothing. */
1815 void
1816 del_range (from, to)
1817 register int from, to;
1819 del_range_1 (from, to, 1, 0);
1822 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1823 RET_STRING says to return the deleted text. */
1825 Lisp_Object
1826 del_range_1 (from, to, prepare, ret_string)
1827 int from, to, prepare, ret_string;
1829 int from_byte, to_byte;
1830 Lisp_Object deletion;
1831 struct gcpro gcpro1;
1833 /* Make args be valid */
1834 if (from < BEGV)
1835 from = BEGV;
1836 if (to > ZV)
1837 to = ZV;
1839 if (to <= from)
1840 return Qnil;
1842 if (prepare)
1844 int range_length = to - from;
1845 prepare_to_modify_buffer (from, to, &from);
1846 to = min (ZV, from + range_length);
1849 from_byte = CHAR_TO_BYTE (from);
1850 to_byte = CHAR_TO_BYTE (to);
1852 deletion = del_range_2 (from, from_byte, to, to_byte, ret_string);
1853 GCPRO1(deletion);
1854 signal_after_change (from, to - from, 0);
1855 update_compositions (from, from, CHECK_HEAD);
1856 UNGCPRO;
1857 return deletion;
1860 /* Like del_range_1 but args are byte positions, not char positions. */
1862 void
1863 del_range_byte (from_byte, to_byte, prepare)
1864 int from_byte, to_byte, prepare;
1866 int from, to;
1868 /* Make args be valid */
1869 if (from_byte < BEGV_BYTE)
1870 from_byte = BEGV_BYTE;
1871 if (to_byte > ZV_BYTE)
1872 to_byte = ZV_BYTE;
1874 if (to_byte <= from_byte)
1875 return;
1877 from = BYTE_TO_CHAR (from_byte);
1878 to = BYTE_TO_CHAR (to_byte);
1880 if (prepare)
1882 int old_from = from, old_to = Z - to;
1883 int range_length = to - from;
1884 prepare_to_modify_buffer (from, to, &from);
1885 to = from + range_length;
1887 if (old_from != from)
1888 from_byte = CHAR_TO_BYTE (from);
1889 if (to > ZV)
1891 to = ZV;
1892 to_byte = ZV_BYTE;
1894 else if (old_to == Z - to)
1895 to_byte = CHAR_TO_BYTE (to);
1898 del_range_2 (from, from_byte, to, to_byte, 0);
1899 signal_after_change (from, to - from, 0);
1900 update_compositions (from, from, CHECK_HEAD);
1903 /* Like del_range_1, but positions are specified both as charpos
1904 and bytepos. */
1906 void
1907 del_range_both (from, from_byte, to, to_byte, prepare)
1908 int from, from_byte, to, to_byte, prepare;
1910 /* Make args be valid */
1911 if (from_byte < BEGV_BYTE)
1912 from_byte = BEGV_BYTE;
1913 if (to_byte > ZV_BYTE)
1914 to_byte = ZV_BYTE;
1916 if (to_byte <= from_byte)
1917 return;
1919 if (from < BEGV)
1920 from = BEGV;
1921 if (to > ZV)
1922 to = ZV;
1924 if (prepare)
1926 int old_from = from, old_to = Z - to;
1927 int range_length = to - from;
1928 prepare_to_modify_buffer (from, to, &from);
1929 to = from + range_length;
1931 if (old_from != from)
1932 from_byte = CHAR_TO_BYTE (from);
1933 if (to > ZV)
1935 to = ZV;
1936 to_byte = ZV_BYTE;
1938 else if (old_to == Z - to)
1939 to_byte = CHAR_TO_BYTE (to);
1942 del_range_2 (from, from_byte, to, to_byte, 0);
1943 signal_after_change (from, to - from, 0);
1944 update_compositions (from, from, CHECK_HEAD);
1947 /* Delete a range of text, specified both as character positions
1948 and byte positions. FROM and TO are character positions,
1949 while FROM_BYTE and TO_BYTE are byte positions.
1950 If RET_STRING is true, the deleted area is returned as a string. */
1952 Lisp_Object
1953 del_range_2 (from, from_byte, to, to_byte, ret_string)
1954 int from, from_byte, to, to_byte, ret_string;
1956 register int nbytes_del, nchars_del;
1957 Lisp_Object deletion;
1959 CHECK_MARKERS ();
1961 nchars_del = to - from;
1962 nbytes_del = to_byte - from_byte;
1964 /* Make sure the gap is somewhere in or next to what we are deleting. */
1965 if (from > GPT)
1966 gap_right (from, from_byte);
1967 if (to < GPT)
1968 gap_left (to, to_byte, 0);
1970 #ifdef BYTE_COMBINING_DEBUG
1971 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte),
1972 Z_BYTE - to_byte, from, from_byte))
1973 abort ();
1974 #endif
1976 if (ret_string || ! EQ (current_buffer->undo_list, Qt))
1977 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1978 else
1979 deletion = Qnil;
1981 /* Relocate all markers pointing into the new, larger gap
1982 to point at the end of the text before the gap.
1983 Do this before recording the deletion,
1984 so that undo handles this after reinserting the text. */
1985 adjust_markers_for_delete (from, from_byte, to, to_byte);
1987 if (! EQ (current_buffer->undo_list, Qt))
1988 record_delete (from, deletion);
1989 MODIFF++;
1990 CHARS_MODIFF = MODIFF;
1992 /* Relocate point as if it were a marker. */
1993 if (from < PT)
1994 adjust_point (from - (PT < to ? PT : to),
1995 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte));
1997 offset_intervals (current_buffer, from, - nchars_del);
1999 /* Adjust the overlay center as needed. This must be done after
2000 adjusting the markers that bound the overlays. */
2001 adjust_overlays_for_delete (from, nchars_del);
2003 GAP_SIZE += nbytes_del;
2004 ZV_BYTE -= nbytes_del;
2005 Z_BYTE -= nbytes_del;
2006 ZV -= nchars_del;
2007 Z -= nchars_del;
2008 GPT = from;
2009 GPT_BYTE = from_byte;
2010 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
2012 if (GPT_BYTE < GPT)
2013 abort ();
2015 if (GPT - BEG < BEG_UNCHANGED)
2016 BEG_UNCHANGED = GPT - BEG;
2017 if (Z - GPT < END_UNCHANGED)
2018 END_UNCHANGED = Z - GPT;
2020 CHECK_MARKERS ();
2022 evaporate_overlays (from);
2024 return deletion;
2027 /* Call this if you're about to change the region of BUFFER from
2028 character positions START to END. This checks the read-only
2029 properties of the region, calls the necessary modification hooks,
2030 and warns the next redisplay that it should pay attention to that
2031 area.
2033 If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
2034 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
2036 void
2037 modify_region (buffer, start, end, preserve_chars_modiff)
2038 struct buffer *buffer;
2039 int start, end, preserve_chars_modiff;
2041 struct buffer *old_buffer = current_buffer;
2043 if (buffer != old_buffer)
2044 set_buffer_internal (buffer);
2046 prepare_to_modify_buffer (start, end, NULL);
2048 BUF_COMPUTE_UNCHANGED (buffer, start - 1, end);
2050 if (MODIFF <= SAVE_MODIFF)
2051 record_first_change ();
2052 MODIFF++;
2053 if (! preserve_chars_modiff)
2054 CHARS_MODIFF = MODIFF;
2056 buffer->point_before_scroll = Qnil;
2058 if (buffer != old_buffer)
2059 set_buffer_internal (old_buffer);
2062 /* Check that it is okay to modify the buffer between START and END,
2063 which are char positions.
2065 Run the before-change-function, if any. If intervals are in use,
2066 verify that the text to be modified is not read-only, and call
2067 any modification properties the text may have.
2069 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2070 by holding its value temporarily in a marker. */
2072 void
2073 prepare_to_modify_buffer (start, end, preserve_ptr)
2074 int start, end;
2075 int *preserve_ptr;
2077 struct buffer *base_buffer;
2079 if (!NILP (current_buffer->read_only))
2080 Fbarf_if_buffer_read_only ();
2082 /* Let redisplay consider other windows than selected_window
2083 if modifying another buffer. */
2084 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
2085 ++windows_or_buffers_changed;
2087 if (BUF_INTERVALS (current_buffer) != 0)
2089 if (preserve_ptr)
2091 Lisp_Object preserve_marker;
2092 struct gcpro gcpro1;
2093 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
2094 GCPRO1 (preserve_marker);
2095 verify_interval_modification (current_buffer, start, end);
2096 *preserve_ptr = marker_position (preserve_marker);
2097 unchain_marker (XMARKER (preserve_marker));
2098 UNGCPRO;
2100 else
2101 verify_interval_modification (current_buffer, start, end);
2104 /* For indirect buffers, use the base buffer to check clashes. */
2105 if (current_buffer->base_buffer != 0)
2106 base_buffer = current_buffer->base_buffer;
2107 else
2108 base_buffer = current_buffer;
2110 #ifdef CLASH_DETECTION
2111 if (!NILP (base_buffer->file_truename)
2112 /* Make binding buffer-file-name to nil effective. */
2113 && !NILP (base_buffer->filename)
2114 && SAVE_MODIFF >= MODIFF)
2115 lock_file (base_buffer->file_truename);
2116 #else
2117 /* At least warn if this file has changed on disk since it was visited. */
2118 if (!NILP (base_buffer->filename)
2119 && SAVE_MODIFF >= MODIFF
2120 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2121 && !NILP (Ffile_exists_p (base_buffer->filename)))
2122 call1 (intern ("ask-user-about-supersession-threat"),
2123 base_buffer->filename);
2124 #endif /* not CLASH_DETECTION */
2126 signal_before_change (start, end, preserve_ptr);
2128 if (current_buffer->newline_cache)
2129 invalidate_region_cache (current_buffer,
2130 current_buffer->newline_cache,
2131 start - BEG, Z - end);
2132 if (current_buffer->width_run_cache)
2133 invalidate_region_cache (current_buffer,
2134 current_buffer->width_run_cache,
2135 start - BEG, Z - end);
2137 Vdeactivate_mark = Qt;
2140 /* These macros work with an argument named `preserve_ptr'
2141 and a local variable named `preserve_marker'. */
2143 #define PRESERVE_VALUE \
2144 if (preserve_ptr && NILP (preserve_marker)) \
2145 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2147 #define RESTORE_VALUE \
2148 if (! NILP (preserve_marker)) \
2150 *preserve_ptr = marker_position (preserve_marker); \
2151 unchain_marker (XMARKER (preserve_marker)); \
2154 #define PRESERVE_START_END \
2155 if (NILP (start_marker)) \
2156 start_marker = Fcopy_marker (start, Qnil); \
2157 if (NILP (end_marker)) \
2158 end_marker = Fcopy_marker (end, Qnil);
2160 #define FETCH_START \
2161 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2163 #define FETCH_END \
2164 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2166 /* Set a variable to nil if an error occurred.
2167 Don't change the variable if there was no error.
2168 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
2169 VARIABLE is the variable to maybe set to nil.
2170 NO-ERROR-FLAG is nil if there was an error,
2171 anything else meaning no error (so this function does nothing). */
2172 Lisp_Object
2173 reset_var_on_error (val)
2174 Lisp_Object val;
2176 if (NILP (XCDR (val)))
2177 Fset (XCAR (val), Qnil);
2178 return Qnil;
2181 /* Signal a change to the buffer immediately before it happens.
2182 START_INT and END_INT are the bounds of the text to be changed.
2184 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2185 by holding its value temporarily in a marker. */
2187 void
2188 signal_before_change (start_int, end_int, preserve_ptr)
2189 int start_int, end_int;
2190 int *preserve_ptr;
2192 Lisp_Object start, end;
2193 Lisp_Object start_marker, end_marker;
2194 Lisp_Object preserve_marker;
2195 struct gcpro gcpro1, gcpro2, gcpro3;
2196 int count = SPECPDL_INDEX ();
2198 if (inhibit_modification_hooks)
2199 return;
2201 start = make_number (start_int);
2202 end = make_number (end_int);
2203 preserve_marker = Qnil;
2204 start_marker = Qnil;
2205 end_marker = Qnil;
2206 GCPRO3 (preserve_marker, start_marker, end_marker);
2208 specbind (Qinhibit_modification_hooks, Qt);
2210 /* If buffer is unmodified, run a special hook for that case. */
2211 if (SAVE_MODIFF >= MODIFF
2212 && !NILP (Vfirst_change_hook)
2213 && !NILP (Vrun_hooks))
2215 PRESERVE_VALUE;
2216 PRESERVE_START_END;
2217 call1 (Vrun_hooks, Qfirst_change_hook);
2220 /* Now run the before-change-functions if any. */
2221 if (!NILP (Vbefore_change_functions))
2223 Lisp_Object args[3];
2224 Lisp_Object rvoe_arg = Fcons (Qbefore_change_functions, Qnil);
2226 PRESERVE_VALUE;
2227 PRESERVE_START_END;
2229 /* Mark before-change-functions to be reset to nil in case of error. */
2230 record_unwind_protect (reset_var_on_error, rvoe_arg);
2232 /* Actually run the hook functions. */
2233 args[0] = Qbefore_change_functions;
2234 args[1] = FETCH_START;
2235 args[2] = FETCH_END;
2236 Frun_hook_with_args (3, args);
2238 /* There was no error: unarm the reset_on_error. */
2239 XSETCDR (rvoe_arg, Qt);
2242 if (current_buffer->overlays_before || current_buffer->overlays_after)
2244 PRESERVE_VALUE;
2245 report_overlay_modification (FETCH_START, FETCH_END, 0,
2246 FETCH_START, FETCH_END, Qnil);
2249 if (! NILP (start_marker))
2250 free_marker (start_marker);
2251 if (! NILP (end_marker))
2252 free_marker (end_marker);
2253 RESTORE_VALUE;
2254 UNGCPRO;
2256 unbind_to (count, Qnil);
2259 /* Signal a change immediately after it happens.
2260 CHARPOS is the character position of the start of the changed text.
2261 LENDEL is the number of characters of the text before the change.
2262 (Not the whole buffer; just the part that was changed.)
2263 LENINS is the number of characters in that part of the text
2264 after the change. */
2266 void
2267 signal_after_change (charpos, lendel, lenins)
2268 int charpos, lendel, lenins;
2270 int count = SPECPDL_INDEX ();
2271 if (inhibit_modification_hooks)
2272 return;
2274 /* If we are deferring calls to the after-change functions
2275 and there are no before-change functions,
2276 just record the args that we were going to use. */
2277 if (! NILP (Vcombine_after_change_calls)
2278 && NILP (Vbefore_change_functions)
2279 && !current_buffer->overlays_before
2280 && !current_buffer->overlays_after)
2282 Lisp_Object elt;
2284 if (!NILP (combine_after_change_list)
2285 && current_buffer != XBUFFER (combine_after_change_buffer))
2286 Fcombine_after_change_execute ();
2288 elt = Fcons (make_number (charpos - BEG),
2289 Fcons (make_number (Z - (charpos - lendel + lenins)),
2290 Fcons (make_number (lenins - lendel), Qnil)));
2291 combine_after_change_list
2292 = Fcons (elt, combine_after_change_list);
2293 combine_after_change_buffer = Fcurrent_buffer ();
2295 return;
2298 if (!NILP (combine_after_change_list))
2299 Fcombine_after_change_execute ();
2301 specbind (Qinhibit_modification_hooks, Qt);
2303 if (!NILP (Vafter_change_functions))
2305 Lisp_Object args[4];
2306 Lisp_Object rvoe_arg = Fcons (Qafter_change_functions, Qnil);
2308 /* Mark after-change-functions to be reset to nil in case of error. */
2309 record_unwind_protect (reset_var_on_error, rvoe_arg);
2311 /* Actually run the hook functions. */
2312 args[0] = Qafter_change_functions;
2313 XSETFASTINT (args[1], charpos);
2314 XSETFASTINT (args[2], charpos + lenins);
2315 XSETFASTINT (args[3], lendel);
2316 Frun_hook_with_args (4, args);
2318 /* There was no error: unarm the reset_on_error. */
2319 XSETCDR (rvoe_arg, Qt);
2322 if (current_buffer->overlays_before || current_buffer->overlays_after)
2323 report_overlay_modification (make_number (charpos),
2324 make_number (charpos + lenins),
2326 make_number (charpos),
2327 make_number (charpos + lenins),
2328 make_number (lendel));
2330 /* After an insertion, call the text properties
2331 insert-behind-hooks or insert-in-front-hooks. */
2332 if (lendel == 0)
2333 report_interval_modification (make_number (charpos),
2334 make_number (charpos + lenins));
2336 unbind_to (count, Qnil);
2339 Lisp_Object
2340 Fcombine_after_change_execute_1 (val)
2341 Lisp_Object val;
2343 Vcombine_after_change_calls = val;
2344 return val;
2347 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
2348 Scombine_after_change_execute, 0, 0, 0,
2349 doc: /* This function is for use internally in `combine-after-change-calls'. */)
2352 int count = SPECPDL_INDEX ();
2353 int beg, end, change;
2354 int begpos, endpos;
2355 Lisp_Object tail;
2357 if (NILP (combine_after_change_list))
2358 return Qnil;
2360 /* It is rare for combine_after_change_buffer to be invalid, but
2361 possible. It can happen when combine-after-change-calls is
2362 non-nil, and insertion calls a file handler (e.g. through
2363 lock_file) which scribbles into a temp file -- cyd */
2364 if (!BUFFERP (combine_after_change_buffer)
2365 || NILP (XBUFFER (combine_after_change_buffer)->name))
2367 combine_after_change_list = Qnil;
2368 return Qnil;
2371 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
2373 Fset_buffer (combine_after_change_buffer);
2375 /* # chars unchanged at beginning of buffer. */
2376 beg = Z - BEG;
2377 /* # chars unchanged at end of buffer. */
2378 end = beg;
2379 /* Total amount of insertion (negative for deletion). */
2380 change = 0;
2382 /* Scan the various individual changes,
2383 accumulating the range info in BEG, END and CHANGE. */
2384 for (tail = combine_after_change_list; CONSP (tail);
2385 tail = XCDR (tail))
2387 Lisp_Object elt;
2388 int thisbeg, thisend, thischange;
2390 /* Extract the info from the next element. */
2391 elt = XCAR (tail);
2392 if (! CONSP (elt))
2393 continue;
2394 thisbeg = XINT (XCAR (elt));
2396 elt = XCDR (elt);
2397 if (! CONSP (elt))
2398 continue;
2399 thisend = XINT (XCAR (elt));
2401 elt = XCDR (elt);
2402 if (! CONSP (elt))
2403 continue;
2404 thischange = XINT (XCAR (elt));
2406 /* Merge this range into the accumulated range. */
2407 change += thischange;
2408 if (thisbeg < beg)
2409 beg = thisbeg;
2410 if (thisend < end)
2411 end = thisend;
2414 /* Get the current start and end positions of the range
2415 that was changed. */
2416 begpos = BEG + beg;
2417 endpos = Z - end;
2419 /* We are about to handle these, so discard them. */
2420 combine_after_change_list = Qnil;
2422 /* Now run the after-change functions for real.
2423 Turn off the flag that defers them. */
2424 record_unwind_protect (Fcombine_after_change_execute_1,
2425 Vcombine_after_change_calls);
2426 signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
2427 update_compositions (begpos, endpos, CHECK_ALL);
2429 return unbind_to (count, Qnil);
2432 void
2433 syms_of_insdel ()
2435 staticpro (&combine_after_change_list);
2436 staticpro (&combine_after_change_buffer);
2437 combine_after_change_list = Qnil;
2438 combine_after_change_buffer = Qnil;
2440 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag,
2441 doc: /* Non-nil means enable debugging checks for invalid marker positions. */);
2442 check_markers_debug_flag = 0;
2443 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
2444 doc: /* Used internally by the `combine-after-change-calls' macro. */);
2445 Vcombine_after_change_calls = Qnil;
2447 DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks,
2448 doc: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2449 This affects `before-change-functions' and `after-change-functions',
2450 as well as hooks attached to text properties and overlays. */);
2451 inhibit_modification_hooks = 0;
2452 Qinhibit_modification_hooks = intern ("inhibit-modification-hooks");
2453 staticpro (&Qinhibit_modification_hooks);
2455 defsubr (&Scombine_after_change_execute);
2458 /* arch-tag: 9b34b886-47d7-465e-a234-299af411b23d
2459 (do not change this comment) */