(del_range_2): Use adjust_markers_for_record_delete.
[bpt/emacs.git] / src / insdel.c
1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 86, 93, 94, 95, 97, 1998 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
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)
9 any later version.
10
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.
15
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. */
20
21
22 #include <config.h>
23 #include "lisp.h"
24 #include "intervals.h"
25 #include "buffer.h"
26 #include "charset.h"
27 #include "window.h"
28 #include "blockinput.h"
29
30 #ifndef NULL
31 #define NULL 0
32 #endif
33
34 #define min(x, y) ((x) < (y) ? (x) : (y))
35
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, int, int));
42 static void adjust_markers_for_delete P_ ((int, int, int, int));
43 static void adjust_markers_for_record_delete P_ ((int, int, int, int));
44 static void adjust_point P_ ((int, int));
45
46 Lisp_Object Fcombine_after_change_execute ();
47
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;
51
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.
56
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;
63
64 /* Buffer which combine_after_change_list is about. */
65 Lisp_Object combine_after_change_buffer;
66 \f
67 /* Move gap to position CHARPOS.
68 Note that this can quit! */
69
70 void
71 move_gap (charpos)
72 int charpos;
73 {
74 move_gap_both (charpos, charpos_to_bytepos (charpos));
75 }
76
77 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
78 Note that this can quit! */
79
80 void
81 move_gap_both (charpos, bytepos)
82 int charpos, bytepos;
83 {
84 if (bytepos < GPT_BYTE)
85 gap_left (charpos, bytepos, 0);
86 else if (bytepos > GPT_BYTE)
87 gap_right (charpos, bytepos);
88 }
89
90 /* Move the gap to a position less than the current GPT.
91 BYTEPOS describes the new position as a byte position,
92 and CHARPOS is the corresponding char position.
93 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
94
95 static void
96 gap_left (charpos, bytepos, newgap)
97 register int charpos, bytepos;
98 int newgap;
99 {
100 register unsigned char *to, *from;
101 register int i;
102 int new_s1;
103
104 if (!newgap)
105 {
106 if (unchanged_modified == MODIFF
107 && overlay_unchanged_modified == OVERLAY_MODIFF)
108 {
109 beg_unchanged = charpos - BEG;
110 end_unchanged = Z - charpos;
111 }
112 else
113 {
114 if (Z - GPT < end_unchanged)
115 end_unchanged = Z - GPT;
116 if (charpos < beg_unchanged)
117 beg_unchanged = charpos - BEG;
118 }
119 }
120
121 i = GPT_BYTE;
122 to = GAP_END_ADDR;
123 from = GPT_ADDR;
124 new_s1 = GPT_BYTE;
125
126 /* Now copy the characters. To move the gap down,
127 copy characters up. */
128
129 while (1)
130 {
131 /* I gets number of characters left to copy. */
132 i = new_s1 - bytepos;
133 if (i == 0)
134 break;
135 /* If a quit is requested, stop copying now.
136 Change BYTEPOS to be where we have actually moved the gap to. */
137 if (QUITP)
138 {
139 bytepos = new_s1;
140 charpos = BYTE_TO_CHAR (bytepos);
141 break;
142 }
143 /* Move at most 32000 chars before checking again for a quit. */
144 if (i > 32000)
145 i = 32000;
146 #ifdef GAP_USE_BCOPY
147 if (i >= 128
148 /* bcopy is safe if the two areas of memory do not overlap
149 or on systems where bcopy is always safe for moving upward. */
150 && (BCOPY_UPWARD_SAFE
151 || to - from >= 128))
152 {
153 /* If overlap is not safe, avoid it by not moving too many
154 characters at once. */
155 if (!BCOPY_UPWARD_SAFE && i > to - from)
156 i = to - from;
157 new_s1 -= i;
158 from -= i, to -= i;
159 bcopy (from, to, i);
160 }
161 else
162 #endif
163 {
164 new_s1 -= i;
165 while (--i >= 0)
166 *--to = *--from;
167 }
168 }
169
170 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
171 BYTEPOS is where the loop above stopped, which may be what was specified
172 or may be where a quit was detected. */
173 adjust_markers_gap_motion (bytepos, GPT_BYTE, GAP_SIZE);
174 GPT_BYTE = bytepos;
175 GPT = charpos;
176 if (bytepos < charpos)
177 abort ();
178 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
179 QUIT;
180 }
181
182 /* Move the gap to a position greater than than the current GPT.
183 BYTEPOS describes the new position as a byte position,
184 and CHARPOS is the corresponding char position. */
185
186 static void
187 gap_right (charpos, bytepos)
188 register int charpos, bytepos;
189 {
190 register unsigned char *to, *from;
191 register int i;
192 int new_s1;
193
194 if (unchanged_modified == MODIFF
195 && overlay_unchanged_modified == OVERLAY_MODIFF)
196 {
197 beg_unchanged = charpos - BEG;
198 end_unchanged = Z - charpos;
199 }
200 else
201 {
202 if (Z - charpos - 1 < end_unchanged)
203 end_unchanged = Z - charpos;
204 if (GPT - BEG < beg_unchanged)
205 beg_unchanged = GPT - BEG;
206 }
207
208 i = GPT_BYTE;
209 from = GAP_END_ADDR;
210 to = GPT_ADDR;
211 new_s1 = GPT_BYTE;
212
213 /* Now copy the characters. To move the gap up,
214 copy characters down. */
215
216 while (1)
217 {
218 /* I gets number of characters left to copy. */
219 i = bytepos - new_s1;
220 if (i == 0)
221 break;
222 /* If a quit is requested, stop copying now.
223 Change BYTEPOS to be where we have actually moved the gap to. */
224 if (QUITP)
225 {
226 bytepos = new_s1;
227 charpos = BYTE_TO_CHAR (bytepos);
228 break;
229 }
230 /* Move at most 32000 chars before checking again for a quit. */
231 if (i > 32000)
232 i = 32000;
233 #ifdef GAP_USE_BCOPY
234 if (i >= 128
235 /* bcopy is safe if the two areas of memory do not overlap
236 or on systems where bcopy is always safe for moving downward. */
237 && (BCOPY_DOWNWARD_SAFE
238 || from - to >= 128))
239 {
240 /* If overlap is not safe, avoid it by not moving too many
241 characters at once. */
242 if (!BCOPY_DOWNWARD_SAFE && i > from - to)
243 i = from - to;
244 new_s1 += i;
245 bcopy (from, to, i);
246 from += i, to += i;
247 }
248 else
249 #endif
250 {
251 new_s1 += i;
252 while (--i >= 0)
253 *to++ = *from++;
254 }
255 }
256
257 adjust_markers_gap_motion (GPT_BYTE + GAP_SIZE, bytepos + GAP_SIZE,
258 - GAP_SIZE);
259 GPT = charpos;
260 GPT_BYTE = bytepos;
261 if (bytepos < charpos)
262 abort ();
263 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
264 QUIT;
265 }
266 \f
267 /* Add AMOUNT to the byte position of every marker in the current buffer
268 whose current byte position is between FROM (exclusive) and TO (inclusive).
269
270 Also, any markers past the outside of that interval, in the direction
271 of adjustment, are first moved back to the near end of the interval
272 and then adjusted by AMOUNT.
273
274 When the latter adjustment is done, if AMOUNT is negative,
275 we record the adjustment for undo. (This case happens only for
276 deletion.)
277
278 The markers' character positions are not altered,
279 because gap motion does not affect character positions. */
280
281 int adjust_markers_test;
282
283 static void
284 adjust_markers_gap_motion (from, to, amount)
285 register int from, to, amount;
286 {
287 /* Now that a marker has a bytepos, not counting the gap,
288 nothing needs to be done here. */
289 #if 0
290 Lisp_Object marker;
291 register struct Lisp_Marker *m;
292 register int mpos;
293
294 marker = BUF_MARKERS (current_buffer);
295
296 while (!NILP (marker))
297 {
298 m = XMARKER (marker);
299 mpos = m->bytepos;
300 if (amount > 0)
301 {
302 if (mpos > to && mpos < to + amount)
303 {
304 if (adjust_markers_test)
305 abort ();
306 mpos = to + amount;
307 }
308 }
309 else
310 {
311 /* Here's the case where a marker is inside text being deleted.
312 AMOUNT can be negative for gap motion, too,
313 but then this range contains no markers. */
314 if (mpos > from + amount && mpos <= from)
315 {
316 if (adjust_markers_test)
317 abort ();
318 mpos = from + amount;
319 }
320 }
321 if (mpos > from && mpos <= to)
322 mpos += amount;
323 m->bufpos = mpos;
324 marker = m->chain;
325 }
326 #endif
327 }
328 \f
329 /* Adjust all markers for a deletion
330 whose range in bytes is FROM_BYTE to TO_BYTE.
331 The range in charpos is FROM to TO.
332
333 This function assumes that the gap is adjacent to
334 or inside of the range being deleted. */
335
336 static void
337 adjust_markers_for_delete (from, from_byte, to, to_byte)
338 register int from, from_byte, to, to_byte;
339 {
340 Lisp_Object marker;
341 register struct Lisp_Marker *m;
342 register int charpos;
343
344 marker = BUF_MARKERS (current_buffer);
345
346 while (!NILP (marker))
347 {
348 m = XMARKER (marker);
349 charpos = m->charpos;
350
351 if (charpos > Z)
352 abort ();
353
354 /* If the marker is after the deletion,
355 relocate by number of chars / bytes deleted. */
356 if (charpos > to)
357 {
358 m->charpos -= to - from;
359 m->bytepos -= to_byte - from_byte;
360 }
361
362 /* Here's the case where a marker is inside text being deleted. */
363 else if (charpos > from)
364 {
365 record_marker_adjustment (marker, from - charpos);
366 m->charpos = from;
367 m->bytepos = from_byte;
368 }
369
370 marker = m->chain;
371 }
372 }
373 \f
374 /* Adjust all markers for calling record_delete for combining bytes.
375 whose range in bytes is FROM_BYTE to TO_BYTE.
376 The range in charpos is FROM to TO. */
377
378 static void
379 adjust_markers_for_record_delete (from, from_byte, to, to_byte)
380 register int from, from_byte, to, to_byte;
381 {
382 Lisp_Object marker;
383 register struct Lisp_Marker *m;
384 register int charpos;
385
386 marker = BUF_MARKERS (current_buffer);
387
388 while (!NILP (marker))
389 {
390 m = XMARKER (marker);
391 charpos = m->charpos;
392
393 /* If the marker is after the deletion,
394 relocate by number of chars / bytes deleted. */
395 if (charpos > to)
396 ;
397 /* Here's the case where a marker is inside text being deleted. */
398 else if (charpos > from)
399 record_marker_adjustment (marker, from - charpos);
400
401 marker = m->chain;
402 }
403 }
404 \f
405 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
406 to TO / TO_BYTE. We have to relocate the charpos of every marker
407 that points after the insertion (but not their bytepos).
408
409 COMBINED_BEFORE_BYTES is the number of bytes at the start of the insertion
410 that combine into one character with the text before the insertion.
411 COMBINED_AFTER_BYTES is the number of bytes after the insertion
412 that combine into one character with the last inserted bytes.
413
414 When a marker points at the insertion point,
415 we advance it if either its insertion-type is t
416 or BEFORE_MARKERS is true. */
417
418 static void
419 adjust_markers_for_insert (from, from_byte, to, to_byte,
420 combined_before_bytes, combined_after_bytes,
421 before_markers)
422 register int from, from_byte, to, to_byte;
423 int combined_before_bytes, combined_after_bytes, before_markers;
424 {
425 Lisp_Object marker;
426 int adjusted = 0;
427 int nchars = to - from;
428 int nbytes = to_byte - from_byte;
429
430 marker = BUF_MARKERS (current_buffer);
431
432 while (!NILP (marker))
433 {
434 register struct Lisp_Marker *m = XMARKER (marker);
435
436 /* In a single-byte buffer, a marker's two positions must be equal.
437 (If this insertion is going to combine characters, Z will
438 become different from Z_BYTE, but they might be the same now.
439 If so, the two OLD positions of the marker should be equal.) */
440 if (Z == Z_BYTE)
441 {
442 if (m->charpos != m->bytepos)
443 abort ();
444 }
445
446 if (m->bytepos == from_byte)
447 {
448 if (m->insertion_type || before_markers)
449 {
450 m->bytepos += nbytes + combined_after_bytes;
451 m->charpos += nchars + !!combined_after_bytes;
452 /* Point the marker before the combined character,
453 so that undoing the insertion puts it back where it was. */
454 if (combined_after_bytes)
455 DEC_BOTH (m->charpos, m->bytepos);
456 if (m->insertion_type)
457 adjusted = 1;
458 }
459 else if (combined_before_bytes)
460 {
461 /* This marker doesn't "need relocation",
462 but don't leave it pointing in the middle of a character.
463 Point the marker after the combined character,
464 so that undoing the insertion puts it back where it was. */
465
466 /* Here we depend on the fact that the gap is after
467 all of the combining bytes that we are going to skip over. */
468 DEC_BOTH (m->charpos, m->bytepos);
469 INC_BOTH (m->charpos, m->bytepos);
470 }
471 }
472 /* If a marker was pointing into the combining bytes
473 after the insertion, don't leave it there
474 in the middle of a character. */
475 else if (combined_after_bytes && m->bytepos >= from_byte
476 && m->bytepos < from_byte + combined_after_bytes)
477 {
478 /* Put it after the combining bytes. */
479 m->bytepos = to_byte + combined_after_bytes;
480 m->charpos = to + 1;
481 /* Now move it back before the combined character,
482 so that undoing the insertion will put it where it was. */
483 DEC_BOTH (m->charpos, m->bytepos);
484 }
485 else if (m->bytepos > from_byte)
486 {
487 m->bytepos += nbytes;
488 m->charpos += nchars;
489 }
490
491 marker = m->chain;
492 }
493
494 /* Adjusting only markers whose insertion-type is t may result in
495 disordered overlays in the slot `overlays_before'. */
496 if (adjusted)
497 fix_overlays_before (current_buffer, from, to);
498 }
499
500 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
501
502 This is used only when the value of point changes due to an insert
503 or delete; it does not represent a conceptual change in point as a
504 marker. In particular, point is not crossing any interval
505 boundaries, so there's no need to use the usual SET_PT macro. In
506 fact it would be incorrect to do so, because either the old or the
507 new value of point is out of sync with the current set of
508 intervals. */
509
510 static void
511 adjust_point (nchars, nbytes)
512 int nchars, nbytes;
513 {
514 BUF_PT (current_buffer) += nchars;
515 BUF_PT_BYTE (current_buffer) += nbytes;
516
517 /* In a single-byte buffer, the two positions must be equal. */
518 if (ZV == ZV_BYTE
519 && PT != PT_BYTE)
520 abort ();
521 }
522 \f
523 /* Make the gap NBYTES_ADDED bytes longer. */
524
525 void
526 make_gap (nbytes_added)
527 int nbytes_added;
528 {
529 unsigned char *result;
530 Lisp_Object tem;
531 int real_gap_loc;
532 int real_gap_loc_byte;
533 int old_gap_size;
534
535 /* If we have to get more space, get enough to last a while. */
536 nbytes_added += 2000;
537
538 /* Don't allow a buffer size that won't fit in an int
539 even if it will fit in a Lisp integer.
540 That won't work because so many places use `int'. */
541
542 if (Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added
543 >= ((unsigned) 1 << (min (BITS_PER_INT, VALBITS) - 1)))
544 error ("Buffer exceeds maximum size");
545
546 BLOCK_INPUT;
547 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */
548 result = BUFFER_REALLOC (BEG_ADDR, (Z_BYTE - BEG_BYTE
549 + GAP_SIZE + nbytes_added + 1));
550
551 if (result == 0)
552 {
553 UNBLOCK_INPUT;
554 memory_full ();
555 }
556
557 /* We can't unblock until the new address is properly stored. */
558 BEG_ADDR = result;
559 UNBLOCK_INPUT;
560
561 /* Prevent quitting in move_gap. */
562 tem = Vinhibit_quit;
563 Vinhibit_quit = Qt;
564
565 real_gap_loc = GPT;
566 real_gap_loc_byte = GPT_BYTE;
567 old_gap_size = GAP_SIZE;
568
569 /* Call the newly allocated space a gap at the end of the whole space. */
570 GPT = Z + GAP_SIZE;
571 GPT_BYTE = Z_BYTE + GAP_SIZE;
572 GAP_SIZE = nbytes_added;
573
574 /* Move the new gap down to be consecutive with the end of the old one.
575 This adjusts the markers properly too. */
576 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
577
578 /* Now combine the two into one large gap. */
579 GAP_SIZE += old_gap_size;
580 GPT = real_gap_loc;
581 GPT_BYTE = real_gap_loc_byte;
582
583 /* Put an anchor. */
584 *(Z_ADDR) = 0;
585
586 Vinhibit_quit = tem;
587 }
588 \f
589 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
590 FROM_MULTIBYTE says whether the incoming text is multibyte.
591 TO_MULTIBYTE says whether to store the text as multibyte.
592 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
593
594 Return the number of bytes stored at TO_ADDR. */
595
596 int
597 copy_text (from_addr, to_addr, nbytes,
598 from_multibyte, to_multibyte)
599 unsigned char *from_addr;
600 unsigned char *to_addr;
601 int nbytes;
602 int from_multibyte, to_multibyte;
603 {
604 if (from_multibyte == to_multibyte)
605 {
606 bcopy (from_addr, to_addr, nbytes);
607 return nbytes;
608 }
609 else if (from_multibyte)
610 {
611 int nchars = 0;
612 int bytes_left = nbytes;
613
614 /* Convert multibyte to single byte. */
615 while (bytes_left > 0)
616 {
617 int thislen, c;
618 c = STRING_CHAR_AND_LENGTH (from_addr, bytes_left, thislen);
619 *to_addr++ = SINGLE_BYTE_CHAR_P (c) ? c : (c & 0177) + 0200;
620 from_addr += thislen;
621 bytes_left--;
622 nchars++;
623 }
624 return nchars;
625 }
626 else
627 {
628 unsigned char *initial_to_addr = to_addr;
629
630 /* Convert single-byte to multibyte. */
631 while (nbytes > 0)
632 {
633 int c = *from_addr++;
634 unsigned char workbuf[4], *str;
635 int len;
636
637 if (c >= 0240 && c < 0400)
638 {
639 c = unibyte_char_to_multibyte (c);
640 len = CHAR_STRING (c, workbuf, str);
641 bcopy (str, to_addr, len);
642 to_addr += len;
643 nbytes--;
644 }
645 else
646 /* Special case for speed. */
647 *to_addr++ = c, nbytes--;
648 }
649 return to_addr - initial_to_addr;
650 }
651 }
652
653 /* Return the number of bytes it would take
654 to convert some single-byte text to multibyte.
655 The single-byte text consists of NBYTES bytes at PTR. */
656
657 int
658 count_size_as_multibyte (ptr, nbytes)
659 unsigned char *ptr;
660 int nbytes;
661 {
662 int i;
663 int outgoing_nbytes = 0;
664
665 for (i = 0; i < nbytes; i++)
666 {
667 unsigned int c = *ptr++;
668
669 if (c < 0240)
670 outgoing_nbytes++;
671 else
672 {
673 c = unibyte_char_to_multibyte (c);
674 outgoing_nbytes += XINT (Fchar_bytes (make_number (c)));
675 }
676 }
677
678 return outgoing_nbytes;
679 }
680 \f
681 /* Insert a string of specified length before point.
682 This function judges multibyteness based on
683 enable_multibyte_characters in the current buffer;
684 it never converts between single-byte and multibyte.
685
686 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
687 prepare_to_modify_buffer could relocate the text. */
688
689 void
690 insert (string, nbytes)
691 register unsigned char *string;
692 register nbytes;
693 {
694 if (nbytes > 0)
695 {
696 int opoint = PT;
697 insert_1 (string, nbytes, 0, 1, 0);
698 signal_after_change (opoint, 0, PT - opoint);
699 }
700 }
701
702 /* Likewise, but inherit text properties from neighboring characters. */
703
704 void
705 insert_and_inherit (string, nbytes)
706 register unsigned char *string;
707 register nbytes;
708 {
709 if (nbytes > 0)
710 {
711 int opoint = PT;
712 insert_1 (string, nbytes, 1, 1, 0);
713 signal_after_change (opoint, 0, PT - opoint);
714 }
715 }
716
717 /* Insert the character C before point. Do not inherit text properties. */
718
719 void
720 insert_char (c)
721 int c;
722 {
723 unsigned char workbuf[4], *str;
724 int len;
725
726 if (! NILP (current_buffer->enable_multibyte_characters))
727 len = CHAR_STRING (c, workbuf, str);
728 else
729 {
730 len = 1;
731 workbuf[0] = c;
732 str = workbuf;
733 }
734
735 insert (str, len);
736 }
737
738 /* Insert the null-terminated string S before point. */
739
740 void
741 insert_string (s)
742 char *s;
743 {
744 insert (s, strlen (s));
745 }
746
747 /* Like `insert' except that all markers pointing at the place where
748 the insertion happens are adjusted to point after it.
749 Don't use this function to insert part of a Lisp string,
750 since gc could happen and relocate it. */
751
752 void
753 insert_before_markers (string, nbytes)
754 unsigned char *string;
755 register int nbytes;
756 {
757 if (nbytes > 0)
758 {
759 int opoint = PT;
760
761 insert_1 (string, nbytes, 0, 1, 1);
762 signal_after_change (opoint, 0, PT - opoint);
763 }
764 }
765
766 /* Likewise, but inherit text properties from neighboring characters. */
767
768 void
769 insert_before_markers_and_inherit (string, nbytes)
770 unsigned char *string;
771 register int nbytes;
772 {
773 if (nbytes > 0)
774 {
775 int opoint = PT;
776
777 insert_1 (string, nbytes, 1, 1, 1);
778 signal_after_change (opoint, 0, PT - opoint);
779 }
780 }
781
782 /* Subroutine used by the insert functions above. */
783
784 void
785 insert_1 (string, nbytes, inherit, prepare, before_markers)
786 register unsigned char *string;
787 register int nbytes;
788 int inherit, prepare, before_markers;
789 {
790 insert_1_both (string, chars_in_text (string, nbytes), nbytes,
791 inherit, prepare, before_markers);
792 }
793 \f
794 /* See if the bytes before POS/POS_BYTE combine with bytes
795 at the start of STRING to form a single character.
796 If so, return the number of bytes at the start of STRING
797 which combine in this way. Otherwise, return 0. */
798
799 int
800 count_combining_before (string, length, pos, pos_byte)
801 unsigned char *string;
802 int length;
803 int pos, pos_byte;
804 {
805 int opos = pos, opos_byte = pos_byte;
806 int c;
807 unsigned char *p = string;
808
809 if (NILP (current_buffer->enable_multibyte_characters))
810 return 0;
811 if (length == 0 || CHAR_HEAD_P (*string))
812 return 0;
813 if (pos == BEGV)
814 return 0;
815 c = FETCH_BYTE (pos_byte - 1);
816 if (ASCII_BYTE_P (c))
817 return 0;
818 DEC_BOTH (pos, pos_byte);
819 c = FETCH_BYTE (pos_byte);
820 if (! BASE_LEADING_CODE_P (c))
821 return 0;
822
823 /* We have a combination situation.
824 Count the bytes at STRING that will combine. */
825 while (!CHAR_HEAD_P (*p) && p < string + length)
826 p++;
827
828 return p - string;
829 }
830
831 /* See if the bytes after POS/POS_BYTE combine with bytes
832 at the end of STRING to form a single character.
833 If so, return the number of bytes after POS/POS_BYTE
834 which combine in this way. Otherwise, return 0. */
835
836 int
837 count_combining_after (string, length, pos, pos_byte)
838 unsigned char *string;
839 int length;
840 int pos, pos_byte;
841 {
842 int opos = pos, opos_byte = pos_byte;
843 int i;
844 int c;
845
846 if (NILP (current_buffer->enable_multibyte_characters))
847 return 0;
848 if (length == 0 || ASCII_BYTE_P (string[length - 1]))
849 return 0;
850 i = length - 1;
851 while (i > 0 && ! CHAR_HEAD_P (string[i]))
852 {
853 i--;
854 }
855 if (! BASE_LEADING_CODE_P (string[i]))
856 return 0;
857
858 if (pos == ZV)
859 return 0;
860 c = FETCH_BYTE (pos_byte);
861 if (CHAR_HEAD_P (c))
862 return 0;
863 while (pos_byte < ZV_BYTE)
864 {
865 c = FETCH_BYTE (pos_byte);
866 if (CHAR_HEAD_P (c))
867 break;
868 pos_byte++;
869 }
870
871 return pos_byte - opos_byte;
872 }
873
874 /* Adjust the position TARGET/TARGET_BYTE for the combining of NBYTES
875 following the position POS/POS_BYTE to the character preceding POS.
876 If TARGET is after POS+NBYTES, we only have to adjust the character
877 position TARGET, else, if TARGET is after POS, we have to adjust
878 both the character position TARGET and the byte position
879 TARGET_BYTE, else we don't have to do any adjustment. */
880
881 #define ADJUST_CHAR_POS(target, target_byte) \
882 do { \
883 if (target > pos + nbytes) \
884 target -= nbytes; \
885 else if (target >= pos) \
886 { \
887 target = pos; \
888 target_byte = pos_byte + nbytes; \
889 } \
890 } while (0)
891
892 /* Combine NBYTES stray trailing-codes, which were formerly separate
893 characters, with the preceding character. These bytes
894 are located after position POS / POS_BYTE, and the preceding character
895 is located just before that position. */
896
897 static void
898 combine_bytes (pos, pos_byte, nbytes)
899 int pos, pos_byte, nbytes;
900 {
901 /* Adjust all markers. */
902 adjust_markers_for_delete (pos, pos_byte, pos + nbytes, pos_byte);
903
904 adjust_overlays_for_delete (pos, nbytes);
905
906 ADJUST_CHAR_POS (BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer));
907 ADJUST_CHAR_POS (GPT, GPT_BYTE);
908 ADJUST_CHAR_POS (Z, Z_BYTE);
909 ADJUST_CHAR_POS (ZV, ZV_BYTE);
910
911 if (BUF_INTERVALS (current_buffer) != 0)
912 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
913 offset_intervals (current_buffer, pos, - nbytes);
914 }
915 \f
916 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
917 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
918 are the same as in insert_1. */
919
920 void
921 insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers)
922 register unsigned char *string;
923 register int nchars, nbytes;
924 int inherit, prepare, before_markers;
925 {
926 register Lisp_Object temp;
927 int combined_before_bytes, combined_after_bytes;
928
929 if (NILP (current_buffer->enable_multibyte_characters))
930 nchars = nbytes;
931
932 if (PT != GPT)
933 move_gap_both (PT, PT_BYTE);
934 if (GAP_SIZE < nbytes)
935 make_gap (nbytes - GAP_SIZE);
936
937 if (prepare)
938 prepare_to_modify_buffer (PT, PT, NULL);
939
940 combined_before_bytes
941 = count_combining_before (string, nbytes, PT, PT_BYTE);
942 combined_after_bytes
943 = count_combining_after (string, nbytes, PT, PT_BYTE);
944
945 /* Record deletion of the surrounding text that combines with
946 the insertion. This, together with recording the insertion,
947 will add up to the right stuff in the undo list.
948
949 But there is no need to actually delete the combining bytes
950 from the buffer and reinsert them. */
951
952 if (combined_after_bytes)
953 {
954 adjust_markers_for_record_delete (PT, PT_BYTE,
955 PT + combined_after_bytes,
956 PT_BYTE + combined_after_bytes);
957 record_delete (PT, combined_after_bytes);
958 }
959
960 if (combined_before_bytes)
961 {
962 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
963 PT, PT_BYTE);
964 record_delete (PT - 1, 1);
965 }
966
967 record_insert (PT - !!combined_before_bytes,
968 nchars - combined_before_bytes + !!combined_before_bytes);
969 MODIFF++;
970
971 bcopy (string, GPT_ADDR, nbytes);
972
973 GAP_SIZE -= nbytes;
974 /* When we have combining at the end of the insertion,
975 this is the character position before the combined character. */
976 GPT += nchars;
977 ZV += nchars;
978 Z += nchars;
979 GPT_BYTE += nbytes;
980 ZV_BYTE += nbytes;
981 Z_BYTE += nbytes;
982 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
983
984 if (combined_after_bytes)
985 move_gap_both (GPT + combined_after_bytes,
986 GPT_BYTE + combined_after_bytes);
987
988 if (GPT_BYTE < GPT)
989 abort ();
990
991 adjust_overlays_for_insert (PT, nchars);
992 adjust_markers_for_insert (PT, PT_BYTE,
993 PT + nchars, PT_BYTE + nbytes,
994 combined_before_bytes, combined_after_bytes,
995 before_markers);
996
997 #ifdef USE_TEXT_PROPERTIES
998 if (BUF_INTERVALS (current_buffer) != 0)
999 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
1000 offset_intervals (current_buffer, PT, nchars);
1001
1002 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
1003 Fset_text_properties (make_number (PT), make_number (PT + nchars),
1004 Qnil, Qnil);
1005 #endif
1006
1007 {
1008 int pos = PT, pos_byte = PT_BYTE;
1009
1010 adjust_point (nchars + combined_after_bytes,
1011 nbytes + combined_after_bytes);
1012
1013 if (combined_after_bytes)
1014 combine_bytes (pos + nchars, pos_byte + nbytes, combined_after_bytes);
1015
1016 if (combined_before_bytes)
1017 combine_bytes (pos, pos_byte, combined_before_bytes);
1018 }
1019 }
1020 \f
1021 /* Insert the part of the text of STRING, a Lisp object assumed to be
1022 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1023 starting at position POS / POS_BYTE. If the text of STRING has properties,
1024 copy them into the buffer.
1025
1026 It does not work to use `insert' for this, because a GC could happen
1027 before we bcopy the stuff into the buffer, and relocate the string
1028 without insert noticing. */
1029
1030 void
1031 insert_from_string (string, pos, pos_byte, length, length_byte, inherit)
1032 Lisp_Object string;
1033 register int pos, pos_byte, length, length_byte;
1034 int inherit;
1035 {
1036 if (length > 0)
1037 {
1038 int opoint = PT;
1039 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1040 inherit, 0);
1041 signal_after_change (opoint, 0, PT - opoint);
1042 }
1043 }
1044
1045 /* Like `insert_from_string' except that all markers pointing
1046 at the place where the insertion happens are adjusted to point after it. */
1047
1048 void
1049 insert_from_string_before_markers (string, pos, pos_byte,
1050 length, length_byte, inherit)
1051 Lisp_Object string;
1052 register int pos, pos_byte, length, length_byte;
1053 int inherit;
1054 {
1055 if (length > 0)
1056 {
1057 int opoint = PT;
1058 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1059 inherit, 1);
1060 signal_after_change (opoint, 0, PT - opoint);
1061 }
1062 }
1063
1064 /* Subroutine of the insertion functions above. */
1065
1066 static void
1067 insert_from_string_1 (string, pos, pos_byte, nchars, nbytes,
1068 inherit, before_markers)
1069 Lisp_Object string;
1070 register int pos, pos_byte, nchars, nbytes;
1071 int inherit, before_markers;
1072 {
1073 register Lisp_Object temp;
1074 struct gcpro gcpro1;
1075 int outgoing_nbytes = nbytes;
1076 int combined_before_bytes, combined_after_bytes;
1077 int adjusted_nchars;
1078 INTERVAL intervals;
1079
1080 /* Make OUTGOING_NBYTES describe the text
1081 as it will be inserted in this buffer. */
1082
1083 if (NILP (current_buffer->enable_multibyte_characters))
1084 outgoing_nbytes = nchars;
1085 else if (nchars == nbytes)
1086 outgoing_nbytes
1087 = count_size_as_multibyte (&XSTRING (string)->data[pos_byte],
1088 nbytes);
1089
1090 /* Make sure point-max won't overflow after this insertion. */
1091 XSETINT (temp, outgoing_nbytes + Z);
1092 if (outgoing_nbytes + Z != XINT (temp))
1093 error ("Maximum buffer size exceeded");
1094
1095 GCPRO1 (string);
1096 prepare_to_modify_buffer (PT, PT, NULL);
1097
1098 if (PT != GPT)
1099 move_gap_both (PT, PT_BYTE);
1100 if (GAP_SIZE < nbytes)
1101 make_gap (outgoing_nbytes - GAP_SIZE);
1102 UNGCPRO;
1103
1104 /* Copy the string text into the buffer, perhaps converting
1105 between single-byte and multibyte. */
1106 copy_text (XSTRING (string)->data + pos_byte, GPT_ADDR, nbytes,
1107 /* If these are equal, it is a single-byte string.
1108 Its chars are either ASCII, in which case copy_text
1109 won't change it, or single-byte non-ASCII chars,
1110 that need to be changed. */
1111 nchars != nbytes,
1112 ! NILP (current_buffer->enable_multibyte_characters));
1113
1114 /* We have copied text into the gap, but we have not altered
1115 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1116 to these functions and get the same results as we would
1117 have got earlier on. Meanwhile, PT_ADDR does point to
1118 the text that has been stored by copy_text. */
1119
1120 combined_before_bytes
1121 = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1122 combined_after_bytes
1123 = count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1124
1125 /* Record deletion of the surrounding text that combines with
1126 the insertion. This, together with recording the insertion,
1127 will add up to the right stuff in the undo list.
1128
1129 But there is no need to actually delete the combining bytes
1130 from the buffer and reinsert them. */
1131
1132 if (combined_after_bytes)
1133 {
1134 adjust_markers_for_record_delete (PT, PT_BYTE,
1135 PT + combined_after_bytes,
1136 PT_BYTE + combined_after_bytes);
1137 record_delete (PT, combined_after_bytes);
1138 }
1139
1140 if (combined_before_bytes)
1141 {
1142 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
1143 PT, PT_BYTE);
1144 record_delete (PT - 1, 1);
1145 }
1146
1147 record_insert (PT - !!combined_before_bytes,
1148 nchars - combined_before_bytes + !!combined_before_bytes);
1149 MODIFF++;
1150
1151 GAP_SIZE -= outgoing_nbytes;
1152 GPT += nchars;
1153 ZV += nchars;
1154 Z += nchars;
1155 GPT_BYTE += outgoing_nbytes;
1156 ZV_BYTE += outgoing_nbytes;
1157 Z_BYTE += outgoing_nbytes;
1158 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1159
1160 if (combined_after_bytes)
1161 move_gap_both (GPT + combined_after_bytes,
1162 GPT_BYTE + combined_after_bytes);
1163
1164 if (GPT_BYTE < GPT)
1165 abort ();
1166
1167 adjust_overlays_for_insert (PT, nchars);
1168 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1169 PT_BYTE + outgoing_nbytes,
1170 combined_before_bytes, combined_after_bytes,
1171 before_markers);
1172
1173 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1174 offset_intervals (current_buffer, PT, nchars);
1175
1176 intervals = XSTRING (string)->intervals;
1177 /* Get the intervals for the part of the string we are inserting--
1178 not including the combined-before bytes. */
1179 if (nbytes < XSTRING (string)->size_byte)
1180 intervals = copy_intervals (intervals, pos, nchars);
1181
1182 /* Insert those intervals. */
1183 graft_intervals_into_buffer (intervals, PT, nchars,
1184 current_buffer, inherit);
1185
1186 {
1187 int pos = PT, pos_byte = PT_BYTE;
1188
1189 adjust_point (nchars + combined_after_bytes,
1190 outgoing_nbytes + combined_after_bytes);
1191
1192 if (combined_after_bytes)
1193 combine_bytes (pos + nchars, pos_byte + outgoing_nbytes,
1194 combined_after_bytes);
1195
1196 if (combined_before_bytes)
1197 combine_bytes (pos, pos_byte, combined_before_bytes);
1198 }
1199 }
1200 \f
1201 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1202 current buffer. If the text in BUF has properties, they are absorbed
1203 into the current buffer.
1204
1205 It does not work to use `insert' for this, because a malloc could happen
1206 and relocate BUF's text before the bcopy happens. */
1207
1208 void
1209 insert_from_buffer (buf, charpos, nchars, inherit)
1210 struct buffer *buf;
1211 int charpos, nchars;
1212 int inherit;
1213 {
1214 if (nchars > 0)
1215 {
1216 int opoint = PT;
1217
1218 insert_from_buffer_1 (buf, charpos, nchars, inherit);
1219 signal_after_change (opoint, 0, PT - opoint);
1220 }
1221 }
1222
1223 static void
1224 insert_from_buffer_1 (buf, from, nchars, inherit)
1225 struct buffer *buf;
1226 int from, nchars;
1227 int inherit;
1228 {
1229 register Lisp_Object temp;
1230 int chunk;
1231 int from_byte = buf_charpos_to_bytepos (buf, from);
1232 int to_byte = buf_charpos_to_bytepos (buf, from + nchars);
1233 int incoming_nbytes = to_byte - from_byte;
1234 int outgoing_nbytes = incoming_nbytes;
1235 int combined_before_bytes, combined_after_bytes;
1236 int adjusted_nchars;
1237 INTERVAL intervals;
1238
1239 /* Make OUTGOING_NBYTES describe the text
1240 as it will be inserted in this buffer. */
1241
1242 if (NILP (current_buffer->enable_multibyte_characters))
1243 outgoing_nbytes = nchars;
1244 else if (NILP (buf->enable_multibyte_characters))
1245 outgoing_nbytes
1246 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf, from_byte),
1247 incoming_nbytes);
1248
1249 /* Make sure point-max won't overflow after this insertion. */
1250 XSETINT (temp, outgoing_nbytes + Z);
1251 if (outgoing_nbytes + Z != XINT (temp))
1252 error ("Maximum buffer size exceeded");
1253
1254 prepare_to_modify_buffer (PT, PT, NULL);
1255
1256 if (PT != GPT)
1257 move_gap_both (PT, PT_BYTE);
1258 if (GAP_SIZE < outgoing_nbytes)
1259 make_gap (outgoing_nbytes - GAP_SIZE);
1260
1261 if (from < BUF_GPT (buf))
1262 {
1263 chunk = BUF_GPT_BYTE (buf) - from_byte;
1264 if (chunk > incoming_nbytes)
1265 chunk = incoming_nbytes;
1266 copy_text (BUF_BYTE_ADDRESS (buf, from_byte),
1267 GPT_ADDR, chunk,
1268 ! NILP (buf->enable_multibyte_characters),
1269 ! NILP (current_buffer->enable_multibyte_characters));
1270 }
1271 else
1272 chunk = 0;
1273 if (chunk < incoming_nbytes)
1274 copy_text (BUF_BYTE_ADDRESS (buf, from_byte + chunk),
1275 GPT_ADDR + chunk, incoming_nbytes - chunk,
1276 ! NILP (buf->enable_multibyte_characters),
1277 ! NILP (current_buffer->enable_multibyte_characters));
1278
1279 /* We have copied text into the gap, but we have not altered
1280 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1281 to these functions and get the same results as we would
1282 have got earlier on. Meanwhile, GPT_ADDR does point to
1283 the text that has been stored by copy_text. */
1284 combined_before_bytes
1285 = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1286 combined_after_bytes
1287 = count_combining_after (GPT_ADDR, outgoing_nbytes,
1288 PT, PT_BYTE);
1289
1290 /* Record deletion of the surrounding text that combines with
1291 the insertion. This, together with recording the insertion,
1292 will add up to the right stuff in the undo list.
1293
1294 But there is no need to actually delete the combining bytes
1295 from the buffer and reinsert them. */
1296
1297 if (combined_after_bytes)
1298 {
1299 adjust_markers_for_record_delete (PT, PT_BYTE,
1300 PT + combined_after_bytes,
1301 PT_BYTE + combined_after_bytes);
1302 record_delete (PT, combined_after_bytes);
1303 }
1304
1305 if (combined_before_bytes)
1306 {
1307 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
1308 PT, PT_BYTE);
1309 record_delete (PT - 1, 1);
1310 }
1311
1312 record_insert (PT - !!combined_before_bytes,
1313 nchars - combined_before_bytes + !!combined_before_bytes);
1314 MODIFF++;
1315
1316 GAP_SIZE -= outgoing_nbytes;
1317 GPT += nchars;
1318 ZV += nchars;
1319 Z += nchars;
1320 GPT_BYTE += outgoing_nbytes;
1321 ZV_BYTE += outgoing_nbytes;
1322 Z_BYTE += outgoing_nbytes;
1323 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1324
1325 if (combined_after_bytes)
1326 move_gap_both (GPT + combined_after_bytes,
1327 GPT_BYTE + combined_after_bytes);
1328
1329 if (GPT_BYTE < GPT)
1330 abort ();
1331
1332 adjust_overlays_for_insert (PT, nchars);
1333 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1334 PT_BYTE + outgoing_nbytes,
1335 combined_before_bytes, combined_after_bytes, 0);
1336
1337 #ifdef USE_TEXT_PROPERTIES
1338 if (BUF_INTERVALS (current_buffer) != 0)
1339 offset_intervals (current_buffer, PT, nchars);
1340 #endif
1341
1342 /* Get the intervals for the part of the string we are inserting--
1343 not including the combined-before bytes. */
1344 intervals = BUF_INTERVALS (buf);
1345 if (outgoing_nbytes < BUF_Z_BYTE (buf) - BUF_BEG_BYTE (buf))
1346 intervals = copy_intervals (intervals, from, nchars);
1347
1348 /* Insert those intervals. */
1349 graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
1350
1351 {
1352 int pos = PT, pos_byte = PT_BYTE;
1353
1354 adjust_point (nchars + combined_after_bytes,
1355 outgoing_nbytes + combined_after_bytes);
1356
1357 if (combined_after_bytes)
1358 combine_bytes (pos + nchars, pos_byte + outgoing_nbytes,
1359 combined_after_bytes);
1360
1361 if (combined_before_bytes)
1362 combine_bytes (pos, pos_byte, combined_before_bytes);
1363 }
1364 }
1365 \f
1366 /* This function should be called after moving gap to FROM and before
1367 altering text between FROM and TO. This adjusts various position
1368 keepers and markers as if the text is deleted. Don't forget to
1369 call adjust_after_replace after you actually alter the text. */
1370
1371 void
1372 adjust_before_replace (from, from_byte, to, to_byte)
1373 int from, from_byte, to, to_byte;
1374 {
1375 adjust_markers_for_delete (from, from_byte, to, to_byte);
1376 record_delete (from, to - from);
1377 adjust_overlays_for_delete (from, to - from);
1378 }
1379
1380 /* This function should be called after altering the text between FROM
1381 and TO to a new text of LEN chars (LEN_BYTE bytes), but before
1382 making the text a buffer contents. It exists just after GPT_ADDR. */
1383
1384 void
1385 adjust_after_replace (from, from_byte, to, to_byte, len, len_byte, replace)
1386 int from, from_byte, to, to_byte, len, len_byte, replace;
1387 {
1388 int combined_before_bytes
1389 = count_combining_before (GPT_ADDR, len_byte, from, from_byte);
1390 int combined_after_bytes
1391 = count_combining_after (GPT_ADDR, len_byte, from, from_byte);
1392
1393 if (combined_after_bytes)
1394 {
1395 adjust_markers_for_record_delete (from, from_byte,
1396 from + combined_after_bytes,
1397 from_byte + combined_after_bytes);
1398 record_delete (from, combined_after_bytes);
1399 }
1400
1401 if (combined_before_bytes)
1402 {
1403 adjust_markers_for_record_delete (from - 1, CHAR_TO_BYTE (from - 1),
1404 from, from_byte);
1405 record_delete (from - 1, 1);
1406 }
1407
1408 /* Update various buffer positions for the new text. */
1409 GAP_SIZE -= len_byte;
1410 ZV += len; Z+= len;
1411 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1412 GPT += len; GPT_BYTE += len_byte;
1413 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1414
1415 if (combined_after_bytes)
1416 move_gap_both (GPT + combined_after_bytes,
1417 GPT_BYTE + combined_after_bytes);
1418
1419 record_insert (from - !!combined_before_bytes,
1420 len - combined_before_bytes + !!combined_before_bytes);
1421 adjust_overlays_for_insert (from, len);
1422 adjust_markers_for_insert (from, from_byte,
1423 from + len, from_byte + len_byte,
1424 combined_before_bytes, combined_after_bytes, 0);
1425 #ifdef USE_TEXT_PROPERTIES
1426 if (BUF_INTERVALS (current_buffer) != 0)
1427 /* REPLACE zero means that we have not yet adjusted the interval
1428 tree for the text between FROM and TO, thus, we must treat the
1429 new text as a newly inserted text, not as a replacement of
1430 something. */
1431 offset_intervals (current_buffer, from, len - (replace ? to - from : 0));
1432 #endif
1433
1434 {
1435 int pos = PT, pos_byte = PT_BYTE;
1436
1437 if (from < PT)
1438 adjust_point (len - (to - from) + combined_after_bytes,
1439 len_byte - (to_byte - from_byte) + combined_after_bytes);
1440 else if (from == PT && combined_before_bytes)
1441 adjust_point (0, combined_before_bytes);
1442
1443 if (combined_after_bytes)
1444 combine_bytes (from + len, from_byte + len_byte, combined_after_bytes);
1445
1446 if (combined_before_bytes)
1447 combine_bytes (from, from_byte, combined_before_bytes);
1448 }
1449
1450 if (len == 0)
1451 evaporate_overlays (from);
1452 MODIFF++;
1453 }
1454
1455 /* Replace the text from character positions FROM to TO with NEW,
1456 If PREPARE is nonzero, call prepare_to_modify_buffer.
1457 If INHERIT, the newly inserted text should inherit text properties
1458 from the surrounding non-deleted text. */
1459
1460 /* Note that this does not yet handle markers quite right.
1461 Also it needs to record a single undo-entry that does a replacement
1462 rather than a separate delete and insert.
1463 That way, undo will also handle markers properly. */
1464
1465 void
1466 replace_range (from, to, new, prepare, inherit)
1467 Lisp_Object new;
1468 int from, to, prepare, inherit;
1469 {
1470 int inschars = XSTRING (new)->size;
1471 int insbytes = XSTRING (new)->size_byte;
1472 int from_byte, to_byte;
1473 int nbytes_del, nchars_del;
1474 register Lisp_Object temp;
1475 struct gcpro gcpro1;
1476 int combined_before_bytes, combined_after_bytes;
1477 int adjusted_inschars;
1478 INTERVAL intervals;
1479 int outgoing_insbytes = insbytes;
1480
1481 GCPRO1 (new);
1482
1483 if (prepare)
1484 {
1485 int range_length = to - from;
1486 prepare_to_modify_buffer (from, to, &from);
1487 to = from + range_length;
1488 }
1489
1490 UNGCPRO;
1491
1492 /* Make args be valid */
1493 if (from < BEGV)
1494 from = BEGV;
1495 if (to > ZV)
1496 to = ZV;
1497
1498 from_byte = CHAR_TO_BYTE (from);
1499 to_byte = CHAR_TO_BYTE (to);
1500
1501 nchars_del = to - from;
1502 nbytes_del = to_byte - from_byte;
1503
1504 if (nbytes_del <= 0 && insbytes == 0)
1505 return;
1506
1507 /* Make OUTGOING_INSBYTES describe the text
1508 as it will be inserted in this buffer. */
1509
1510 if (NILP (current_buffer->enable_multibyte_characters))
1511 outgoing_insbytes = inschars;
1512 else if (inschars == insbytes)
1513 outgoing_insbytes
1514 = count_size_as_multibyte (XSTRING (new)->data, insbytes);
1515
1516 /* Make sure point-max won't overflow after this insertion. */
1517 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1518 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1519 error ("Maximum buffer size exceeded");
1520
1521 GCPRO1 (new);
1522
1523 /* Make sure the gap is somewhere in or next to what we are deleting. */
1524 if (from > GPT)
1525 gap_right (from, from_byte);
1526 if (to < GPT)
1527 gap_left (to, to_byte, 0);
1528
1529 /* Relocate all markers pointing into the new, larger gap
1530 to point at the end of the text before the gap.
1531 Do this before recording the deletion,
1532 so that undo handles this after reinserting the text. */
1533 adjust_markers_for_delete (from, from_byte, to, to_byte);
1534
1535 record_delete (from, nchars_del);
1536
1537 GAP_SIZE += nbytes_del;
1538 ZV -= nchars_del;
1539 Z -= nchars_del;
1540 ZV_BYTE -= nbytes_del;
1541 Z_BYTE -= nbytes_del;
1542 GPT = from;
1543 GPT_BYTE = from_byte;
1544 *(GPT_ADDR) = 0; /* Put an anchor. */
1545
1546 if (GPT_BYTE < GPT)
1547 abort ();
1548
1549 if (GPT - BEG < beg_unchanged)
1550 beg_unchanged = GPT - BEG;
1551 if (Z - GPT < end_unchanged)
1552 end_unchanged = Z - GPT;
1553
1554 if (GAP_SIZE < insbytes)
1555 make_gap (insbytes - GAP_SIZE);
1556
1557 /* Copy the string text into the buffer, perhaps converting
1558 between single-byte and multibyte. */
1559 copy_text (XSTRING (new)->data, GPT_ADDR, insbytes,
1560 /* If these are equal, it is a single-byte string.
1561 Its chars are either ASCII, in which case copy_text
1562 won't change it, or single-byte non-ASCII chars,
1563 that need to be changed. */
1564 inschars != insbytes,
1565 ! NILP (current_buffer->enable_multibyte_characters));
1566
1567 /* We have copied text into the gap, but we have not altered
1568 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1569 to these functions and get the same results as we would
1570 have got earlier on. Meanwhile, GPT_ADDR does point to
1571 the text that has been stored by copy_text. */
1572
1573 combined_before_bytes
1574 = count_combining_before (GPT_ADDR, outgoing_insbytes, PT, PT_BYTE);
1575 combined_after_bytes
1576 = count_combining_after (GPT_ADDR, outgoing_insbytes, PT, PT_BYTE);
1577
1578 /* Record deletion of the surrounding text that combines with
1579 the insertion. This, together with recording the insertion,
1580 will add up to the right stuff in the undo list.
1581
1582 But there is no need to actually delete the combining bytes
1583 from the buffer and reinsert them. */
1584
1585 if (combined_after_bytes)
1586 {
1587 adjust_markers_for_record_delete (PT, PT_BYTE,
1588 PT + combined_after_bytes,
1589 PT_BYTE + combined_after_bytes);
1590 record_delete (PT, combined_after_bytes);
1591 }
1592
1593 if (combined_before_bytes)
1594 {
1595 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
1596 PT, PT_BYTE);
1597 record_delete (PT - 1, 1);
1598 }
1599
1600 record_insert (PT - !!combined_before_bytes,
1601 inschars - combined_before_bytes + !!combined_before_bytes);
1602
1603 GAP_SIZE -= outgoing_insbytes;
1604 GPT += inschars;
1605 ZV += inschars;
1606 Z += inschars;
1607 GPT_BYTE += outgoing_insbytes;
1608 ZV_BYTE += outgoing_insbytes;
1609 Z_BYTE += outgoing_insbytes;
1610 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1611
1612 if (combined_after_bytes)
1613 move_gap_both (GPT + combined_after_bytes,
1614 GPT_BYTE + combined_after_bytes);
1615
1616 if (GPT_BYTE < GPT)
1617 abort ();
1618
1619 /* Adjust the overlay center as needed. This must be done after
1620 adjusting the markers that bound the overlays. */
1621 adjust_overlays_for_delete (from, nchars_del);
1622 adjust_overlays_for_insert (from, inschars);
1623 adjust_markers_for_insert (from, from_byte,
1624 from + inschars, from_byte + outgoing_insbytes,
1625 combined_before_bytes, combined_after_bytes, 0);
1626
1627 #ifdef USE_TEXT_PROPERTIES
1628 offset_intervals (current_buffer, PT, inschars - nchars_del);
1629
1630 /* Get the intervals for the part of the string we are inserting--
1631 not including the combined-before bytes. */
1632 intervals = XSTRING (new)->intervals;
1633 /* Insert those intervals. */
1634 graft_intervals_into_buffer (intervals, from, inschars,
1635 current_buffer, inherit);
1636 #endif
1637
1638 /* Relocate point as if it were a marker. */
1639 if (from < PT)
1640 adjust_point ((from + inschars - (PT < to ? PT : to)
1641 + combined_after_bytes),
1642 (from_byte + outgoing_insbytes
1643 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)
1644 + combined_after_bytes));
1645
1646 if (combined_after_bytes)
1647 combine_bytes (from + inschars, from_byte + outgoing_insbytes,
1648 combined_after_bytes);
1649
1650 if (combined_before_bytes)
1651 combine_bytes (from, from_byte, combined_before_bytes);
1652
1653 if (outgoing_insbytes == 0)
1654 evaporate_overlays (from);
1655
1656 MODIFF++;
1657 UNGCPRO;
1658
1659 signal_after_change (from, nchars_del, PT - from);
1660 }
1661 \f
1662 /* Delete characters in current buffer
1663 from FROM up to (but not including) TO.
1664 If TO comes before FROM, we delete nothing. */
1665
1666 void
1667 del_range (from, to)
1668 register int from, to;
1669 {
1670 del_range_1 (from, to, 1);
1671 }
1672
1673 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
1674
1675 void
1676 del_range_1 (from, to, prepare)
1677 int from, to, prepare;
1678 {
1679 int from_byte, to_byte;
1680
1681 /* Make args be valid */
1682 if (from < BEGV)
1683 from = BEGV;
1684 if (to > ZV)
1685 to = ZV;
1686
1687 if (to <= from)
1688 return;
1689
1690 if (prepare)
1691 {
1692 int range_length = to - from;
1693 prepare_to_modify_buffer (from, to, &from);
1694 to = from + range_length;
1695 }
1696
1697 from_byte = CHAR_TO_BYTE (from);
1698 to_byte = CHAR_TO_BYTE (to);
1699
1700 del_range_2 (from, from_byte, to, to_byte);
1701 }
1702
1703 /* Like del_range_1 but args are byte positions, not char positions. */
1704
1705 void
1706 del_range_byte (from_byte, to_byte, prepare)
1707 int from_byte, to_byte, prepare;
1708 {
1709 int from, to;
1710
1711 /* Make args be valid */
1712 if (from_byte < BEGV_BYTE)
1713 from_byte = BEGV_BYTE;
1714 if (to_byte > ZV_BYTE)
1715 to_byte = ZV_BYTE;
1716
1717 if (to_byte <= from_byte)
1718 return;
1719
1720 from = BYTE_TO_CHAR (from_byte);
1721 to = BYTE_TO_CHAR (to_byte);
1722
1723 if (prepare)
1724 {
1725 int old_from = from, old_to = Z - to;
1726 int range_length = to - from;
1727 prepare_to_modify_buffer (from, to, &from);
1728 to = from + range_length;
1729
1730 if (old_from != from)
1731 from_byte = CHAR_TO_BYTE (from);
1732 if (old_to == Z - to)
1733 to_byte = CHAR_TO_BYTE (to);
1734 }
1735
1736 del_range_2 (from, from_byte, to, to_byte);
1737 }
1738
1739 /* Like del_range_1, but positions are specified both as charpos
1740 and bytepos. */
1741
1742 void
1743 del_range_both (from, from_byte, to, to_byte, prepare)
1744 int from, from_byte, to, to_byte, prepare;
1745 {
1746 /* Make args be valid */
1747 if (from_byte < BEGV_BYTE)
1748 from_byte = BEGV_BYTE;
1749 if (to_byte > ZV_BYTE)
1750 to_byte = ZV_BYTE;
1751
1752 if (to_byte <= from_byte)
1753 return;
1754
1755 if (from < BEGV)
1756 from = BEGV;
1757 if (to > ZV)
1758 to = ZV;
1759
1760 if (prepare)
1761 {
1762 int old_from = from, old_to = Z - to;
1763 int range_length = to - from;
1764 prepare_to_modify_buffer (from, to, &from);
1765 to = from + range_length;
1766
1767 if (old_from != from)
1768 from_byte = CHAR_TO_BYTE (from);
1769 if (old_to == Z - to)
1770 to_byte = CHAR_TO_BYTE (to);
1771 }
1772
1773 del_range_2 (from, from_byte, to, to_byte);
1774 }
1775
1776 /* Delete a range of text, specified both as character positions
1777 and byte positions. FROM and TO are character positions,
1778 while FROM_BYTE and TO_BYTE are byte positions. */
1779
1780 void
1781 del_range_2 (from, from_byte, to, to_byte)
1782 int from, from_byte, to, to_byte;
1783 {
1784 register int nbytes_del, nchars_del;
1785 int combined_after_bytes;
1786
1787 nchars_del = to - from;
1788 nbytes_del = to_byte - from_byte;
1789
1790 /* Make sure the gap is somewhere in or next to what we are deleting. */
1791 if (from > GPT)
1792 gap_right (from, from_byte);
1793 if (to < GPT)
1794 gap_left (to, to_byte, 0);
1795
1796 combined_after_bytes
1797 = count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte),
1798 ZV_BYTE - to_byte, from, from_byte);
1799
1800 /* Relocate all markers pointing into the new, larger gap
1801 to point at the end of the text before the gap.
1802 Do this before recording the deletion,
1803 so that undo handles this after reinserting the text. */
1804 adjust_markers_for_delete (from, from_byte, to, to_byte);
1805 if (combined_after_bytes)
1806 {
1807 int from_byte_1 = from_byte;
1808 DEC_POS (from_byte_1);
1809
1810 /* Adjust markers for the phony deletion
1811 that we are about to call record_undo for. */
1812
1813 /* Here we delete the markers that formerly
1814 pointed at TO ... TO + COMBINED_AFTER_BYTES.
1815 But because of the call to adjust_markers_for_delete, above,
1816 they now point at FROM ... FROM + COMBINED_AFTER_BYTES. */
1817 adjust_markers_for_record_delete (from, from_byte,
1818 from + combined_after_bytes,
1819 from_byte + combined_after_bytes);
1820
1821 adjust_markers_for_record_delete (from - 1, from_byte_1,
1822 from, from_byte);
1823 }
1824 record_delete (from - !!combined_after_bytes,
1825 nchars_del + combined_after_bytes + !!combined_after_bytes);
1826
1827 if (combined_after_bytes)
1828 /* COMBINED_AFTER_BYTES nonzero means that the above record_delete
1829 moved the gap by calling Fbuffer_substring. We must move the
1830 gap again to a proper place. */
1831 move_gap_both (from, from_byte);
1832 MODIFF++;
1833
1834 /* Relocate point as if it were a marker. */
1835 if (from < PT)
1836 adjust_point (from - (PT < to ? PT : to),
1837 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte));
1838
1839 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1840 offset_intervals (current_buffer, from, - nchars_del);
1841
1842 /* Adjust the overlay center as needed. This must be done after
1843 adjusting the markers that bound the overlays. */
1844 adjust_overlays_for_delete (from, nchars_del);
1845
1846 GAP_SIZE += nbytes_del;
1847 ZV_BYTE -= nbytes_del;
1848 Z_BYTE -= nbytes_del;
1849 ZV -= nchars_del;
1850 Z -= nchars_del;
1851 GPT = from;
1852 GPT_BYTE = from_byte;
1853
1854 if (combined_after_bytes)
1855 move_gap_both (GPT + combined_after_bytes,
1856 GPT_BYTE + combined_after_bytes);
1857
1858 *(GPT_ADDR) = 0; /* Put an anchor. */
1859
1860 if (GPT_BYTE < GPT)
1861 abort ();
1862
1863 if (GPT - BEG < beg_unchanged)
1864 beg_unchanged = GPT - BEG;
1865 if (Z - GPT < end_unchanged)
1866 end_unchanged = Z - GPT;
1867
1868 if (combined_after_bytes)
1869 {
1870 combine_bytes (from, from_byte, combined_after_bytes);
1871
1872 record_insert (GPT - 1, 1);
1873 }
1874
1875 evaporate_overlays (from);
1876 signal_after_change (from, nchars_del, 0);
1877 }
1878 \f
1879 /* Call this if you're about to change the region of BUFFER from
1880 character positions START to END. This checks the read-only
1881 properties of the region, calls the necessary modification hooks,
1882 and warns the next redisplay that it should pay attention to that
1883 area. */
1884
1885 void
1886 modify_region (buffer, start, end)
1887 struct buffer *buffer;
1888 int start, end;
1889 {
1890 struct buffer *old_buffer = current_buffer;
1891
1892 if (buffer != old_buffer)
1893 set_buffer_internal (buffer);
1894
1895 prepare_to_modify_buffer (start, end, NULL);
1896
1897 if (start - 1 < beg_unchanged
1898 || (unchanged_modified == MODIFF
1899 && overlay_unchanged_modified == OVERLAY_MODIFF))
1900 beg_unchanged = start - 1;
1901 if (Z - end < end_unchanged
1902 || (unchanged_modified == MODIFF
1903 && overlay_unchanged_modified == OVERLAY_MODIFF))
1904 end_unchanged = Z - end;
1905
1906 if (MODIFF <= SAVE_MODIFF)
1907 record_first_change ();
1908 MODIFF++;
1909
1910 buffer->point_before_scroll = Qnil;
1911
1912 if (buffer != old_buffer)
1913 set_buffer_internal (old_buffer);
1914 }
1915 \f
1916 /* Check that it is okay to modify the buffer between START and END,
1917 which are char positions.
1918
1919 Run the before-change-function, if any. If intervals are in use,
1920 verify that the text to be modified is not read-only, and call
1921 any modification properties the text may have.
1922
1923 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1924 by holding its value temporarily in a marker. */
1925
1926 void
1927 prepare_to_modify_buffer (start, end, preserve_ptr)
1928 int start, end;
1929 int *preserve_ptr;
1930 {
1931 if (!NILP (current_buffer->read_only))
1932 Fbarf_if_buffer_read_only ();
1933
1934 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1935 if (BUF_INTERVALS (current_buffer) != 0)
1936 {
1937 if (preserve_ptr)
1938 {
1939 Lisp_Object preserve_marker;
1940 struct gcpro gcpro1;
1941 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
1942 GCPRO1 (preserve_marker);
1943 verify_interval_modification (current_buffer, start, end);
1944 *preserve_ptr = marker_position (preserve_marker);
1945 unchain_marker (preserve_marker);
1946 UNGCPRO;
1947 }
1948 else
1949 verify_interval_modification (current_buffer, start, end);
1950 }
1951
1952 #ifdef CLASH_DETECTION
1953 if (!NILP (current_buffer->file_truename)
1954 /* Make binding buffer-file-name to nil effective. */
1955 && !NILP (current_buffer->filename)
1956 && SAVE_MODIFF >= MODIFF)
1957 lock_file (current_buffer->file_truename);
1958 #else
1959 /* At least warn if this file has changed on disk since it was visited. */
1960 if (!NILP (current_buffer->filename)
1961 && SAVE_MODIFF >= MODIFF
1962 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
1963 && !NILP (Ffile_exists_p (current_buffer->filename)))
1964 call1 (intern ("ask-user-about-supersession-threat"),
1965 current_buffer->filename);
1966 #endif /* not CLASH_DETECTION */
1967
1968 signal_before_change (start, end, preserve_ptr);
1969
1970 if (current_buffer->newline_cache)
1971 invalidate_region_cache (current_buffer,
1972 current_buffer->newline_cache,
1973 start - BEG, Z - end);
1974 if (current_buffer->width_run_cache)
1975 invalidate_region_cache (current_buffer,
1976 current_buffer->width_run_cache,
1977 start - BEG, Z - end);
1978
1979 Vdeactivate_mark = Qt;
1980 }
1981 \f
1982 /* These macros work with an argument named `preserve_ptr'
1983 and a local variable named `preserve_marker'. */
1984
1985 #define PRESERVE_VALUE \
1986 if (preserve_ptr && NILP (preserve_marker)) \
1987 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
1988
1989 #define RESTORE_VALUE \
1990 if (! NILP (preserve_marker)) \
1991 { \
1992 *preserve_ptr = marker_position (preserve_marker); \
1993 unchain_marker (preserve_marker); \
1994 }
1995
1996 #define PRESERVE_START_END \
1997 if (NILP (start_marker)) \
1998 start_marker = Fcopy_marker (start, Qnil); \
1999 if (NILP (end_marker)) \
2000 end_marker = Fcopy_marker (end, Qnil);
2001
2002 #define FETCH_START \
2003 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2004
2005 #define FETCH_END \
2006 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2007
2008 /* Signal a change to the buffer immediately before it happens.
2009 START_INT and END_INT are the bounds of the text to be changed.
2010
2011 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2012 by holding its value temporarily in a marker. */
2013
2014 void
2015 signal_before_change (start_int, end_int, preserve_ptr)
2016 int start_int, end_int;
2017 int *preserve_ptr;
2018 {
2019 Lisp_Object start, end;
2020 Lisp_Object start_marker, end_marker;
2021 Lisp_Object preserve_marker;
2022 struct gcpro gcpro1, gcpro2, gcpro3;
2023
2024 start = make_number (start_int);
2025 end = make_number (end_int);
2026 preserve_marker = Qnil;
2027 start_marker = Qnil;
2028 end_marker = Qnil;
2029 GCPRO3 (preserve_marker, start_marker, end_marker);
2030
2031 /* If buffer is unmodified, run a special hook for that case. */
2032 if (SAVE_MODIFF >= MODIFF
2033 && !NILP (Vfirst_change_hook)
2034 && !NILP (Vrun_hooks))
2035 {
2036 PRESERVE_VALUE;
2037 PRESERVE_START_END;
2038 call1 (Vrun_hooks, Qfirst_change_hook);
2039 }
2040
2041 /* Run the before-change-function if any.
2042 We don't bother "binding" this variable to nil
2043 because it is obsolete anyway and new code should not use it. */
2044 if (!NILP (Vbefore_change_function))
2045 {
2046 PRESERVE_VALUE;
2047 PRESERVE_START_END;
2048 call2 (Vbefore_change_function, FETCH_START, FETCH_END);
2049 }
2050
2051 /* Now run the before-change-functions if any. */
2052 if (!NILP (Vbefore_change_functions))
2053 {
2054 Lisp_Object args[3];
2055 Lisp_Object before_change_functions;
2056 Lisp_Object after_change_functions;
2057 struct gcpro gcpro1, gcpro2;
2058
2059 PRESERVE_VALUE;
2060 PRESERVE_START_END;
2061
2062 /* "Bind" before-change-functions and after-change-functions
2063 to nil--but in a way that errors don't know about.
2064 That way, if there's an error in them, they will stay nil. */
2065 before_change_functions = Vbefore_change_functions;
2066 after_change_functions = Vafter_change_functions;
2067 Vbefore_change_functions = Qnil;
2068 Vafter_change_functions = Qnil;
2069 GCPRO2 (before_change_functions, after_change_functions);
2070
2071 /* Actually run the hook functions. */
2072 args[0] = Qbefore_change_functions;
2073 args[1] = FETCH_START;
2074 args[2] = FETCH_END;
2075 run_hook_list_with_args (before_change_functions, 3, args);
2076
2077 /* "Unbind" the variables we "bound" to nil. */
2078 Vbefore_change_functions = before_change_functions;
2079 Vafter_change_functions = after_change_functions;
2080 UNGCPRO;
2081 }
2082
2083 if (!NILP (current_buffer->overlays_before)
2084 || !NILP (current_buffer->overlays_after))
2085 {
2086 PRESERVE_VALUE;
2087 report_overlay_modification (FETCH_START, FETCH_END, 0,
2088 FETCH_START, FETCH_END, Qnil);
2089 }
2090
2091 if (! NILP (start_marker))
2092 free_marker (start_marker);
2093 if (! NILP (end_marker))
2094 free_marker (end_marker);
2095 RESTORE_VALUE;
2096 UNGCPRO;
2097 }
2098
2099 /* Signal a change immediately after it happens.
2100 CHARPOS is the character position of the start of the changed text.
2101 LENDEL is the number of characters of the text before the change.
2102 (Not the whole buffer; just the part that was changed.)
2103 LENINS is the number of characters in that part of the text
2104 after the change. */
2105
2106 void
2107 signal_after_change (charpos, lendel, lenins)
2108 int charpos, lendel, lenins;
2109 {
2110 /* If we are deferring calls to the after-change functions
2111 and there are no before-change functions,
2112 just record the args that we were going to use. */
2113 if (! NILP (Vcombine_after_change_calls)
2114 && NILP (Vbefore_change_function) && NILP (Vbefore_change_functions)
2115 && NILP (current_buffer->overlays_before)
2116 && NILP (current_buffer->overlays_after))
2117 {
2118 Lisp_Object elt;
2119
2120 if (!NILP (combine_after_change_list)
2121 && current_buffer != XBUFFER (combine_after_change_buffer))
2122 Fcombine_after_change_execute ();
2123
2124 elt = Fcons (make_number (charpos - BEG),
2125 Fcons (make_number (Z - (charpos - lendel + lenins)),
2126 Fcons (make_number (lenins - lendel), Qnil)));
2127 combine_after_change_list
2128 = Fcons (elt, combine_after_change_list);
2129 combine_after_change_buffer = Fcurrent_buffer ();
2130
2131 return;
2132 }
2133
2134 if (!NILP (combine_after_change_list))
2135 Fcombine_after_change_execute ();
2136
2137 /* Run the after-change-function if any.
2138 We don't bother "binding" this variable to nil
2139 because it is obsolete anyway and new code should not use it. */
2140 if (!NILP (Vafter_change_function))
2141 call3 (Vafter_change_function,
2142 make_number (charpos), make_number (charpos + lenins),
2143 make_number (lendel));
2144
2145 if (!NILP (Vafter_change_functions))
2146 {
2147 Lisp_Object args[4];
2148 Lisp_Object before_change_functions;
2149 Lisp_Object after_change_functions;
2150 struct gcpro gcpro1, gcpro2;
2151
2152 /* "Bind" before-change-functions and after-change-functions
2153 to nil--but in a way that errors don't know about.
2154 That way, if there's an error in them, they will stay nil. */
2155 before_change_functions = Vbefore_change_functions;
2156 after_change_functions = Vafter_change_functions;
2157 Vbefore_change_functions = Qnil;
2158 Vafter_change_functions = Qnil;
2159 GCPRO2 (before_change_functions, after_change_functions);
2160
2161 /* Actually run the hook functions. */
2162 args[0] = Qafter_change_functions;
2163 XSETFASTINT (args[1], charpos);
2164 XSETFASTINT (args[2], charpos + lenins);
2165 XSETFASTINT (args[3], lendel);
2166 run_hook_list_with_args (after_change_functions,
2167 4, args);
2168
2169 /* "Unbind" the variables we "bound" to nil. */
2170 Vbefore_change_functions = before_change_functions;
2171 Vafter_change_functions = after_change_functions;
2172 UNGCPRO;
2173 }
2174
2175 if (!NILP (current_buffer->overlays_before)
2176 || !NILP (current_buffer->overlays_after))
2177 report_overlay_modification (make_number (charpos),
2178 make_number (charpos + lenins),
2179 1,
2180 make_number (charpos),
2181 make_number (charpos + lenins),
2182 make_number (lendel));
2183
2184 /* After an insertion, call the text properties
2185 insert-behind-hooks or insert-in-front-hooks. */
2186 if (lendel == 0)
2187 report_interval_modification (charpos, charpos + lenins);
2188 }
2189
2190 Lisp_Object
2191 Fcombine_after_change_execute_1 (val)
2192 Lisp_Object val;
2193 {
2194 Vcombine_after_change_calls = val;
2195 return val;
2196 }
2197
2198 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
2199 Scombine_after_change_execute, 0, 0, 0,
2200 "This function is for use internally in `combine-after-change-calls'.")
2201 ()
2202 {
2203 register Lisp_Object val;
2204 int count = specpdl_ptr - specpdl;
2205 int beg, end, change;
2206 int begpos, endpos;
2207 Lisp_Object tail;
2208
2209 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
2210
2211 Fset_buffer (combine_after_change_buffer);
2212
2213 /* # chars unchanged at beginning of buffer. */
2214 beg = Z - BEG;
2215 /* # chars unchanged at end of buffer. */
2216 end = beg;
2217 /* Total amount of insertion (negative for deletion). */
2218 change = 0;
2219
2220 /* Scan the various individual changes,
2221 accumulating the range info in BEG, END and CHANGE. */
2222 for (tail = combine_after_change_list; CONSP (tail);
2223 tail = XCONS (tail)->cdr)
2224 {
2225 Lisp_Object elt;
2226 int thisbeg, thisend, thischange;
2227
2228 /* Extract the info from the next element. */
2229 elt = XCONS (tail)->car;
2230 if (! CONSP (elt))
2231 continue;
2232 thisbeg = XINT (XCONS (elt)->car);
2233
2234 elt = XCONS (elt)->cdr;
2235 if (! CONSP (elt))
2236 continue;
2237 thisend = XINT (XCONS (elt)->car);
2238
2239 elt = XCONS (elt)->cdr;
2240 if (! CONSP (elt))
2241 continue;
2242 thischange = XINT (XCONS (elt)->car);
2243
2244 /* Merge this range into the accumulated range. */
2245 change += thischange;
2246 if (thisbeg < beg)
2247 beg = thisbeg;
2248 if (thisend < end)
2249 end = thisend;
2250 }
2251
2252 /* Get the current start and end positions of the range
2253 that was changed. */
2254 begpos = BEG + beg;
2255 endpos = Z - end;
2256
2257 /* We are about to handle these, so discard them. */
2258 combine_after_change_list = Qnil;
2259
2260 /* Now run the after-change functions for real.
2261 Turn off the flag that defers them. */
2262 record_unwind_protect (Fcombine_after_change_execute_1,
2263 Vcombine_after_change_calls);
2264 signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
2265
2266 return unbind_to (count, val);
2267 }
2268 \f
2269 syms_of_insdel ()
2270 {
2271 staticpro (&combine_after_change_list);
2272 combine_after_change_list = Qnil;
2273
2274 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
2275 "Used internally by the `combine-after-change-calls' macro.");
2276 Vcombine_after_change_calls = Qnil;
2277
2278 defsubr (&Scombine_after_change_execute);
2279 }