(internal_self_insert): Pass new arg to replace_range.
[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, deletion;
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 deletion = make_buffer_string_both (PT, PT_BYTE,
955 PT + combined_after_bytes,
956 PT_BYTE + combined_after_bytes, 1);
957
958 adjust_markers_for_record_delete (PT, PT_BYTE,
959 PT + combined_after_bytes,
960 PT_BYTE + combined_after_bytes);
961 record_delete (PT, deletion);
962 }
963
964 if (combined_before_bytes)
965 {
966 deletion = make_buffer_string_both (PT - 1, CHAR_TO_BYTE (PT - 1),
967 PT, PT_BYTE, 1);
968 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
969 PT, PT_BYTE);
970 record_delete (PT - 1, deletion);
971 }
972
973 record_insert (PT - !!combined_before_bytes,
974 nchars - combined_before_bytes + !!combined_before_bytes);
975 MODIFF++;
976
977 bcopy (string, GPT_ADDR, nbytes);
978
979 GAP_SIZE -= nbytes;
980 /* When we have combining at the end of the insertion,
981 this is the character position before the combined character. */
982 GPT += nchars;
983 ZV += nchars;
984 Z += nchars;
985 GPT_BYTE += nbytes;
986 ZV_BYTE += nbytes;
987 Z_BYTE += nbytes;
988 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
989
990 if (combined_after_bytes)
991 move_gap_both (GPT + combined_after_bytes,
992 GPT_BYTE + combined_after_bytes);
993
994 if (GPT_BYTE < GPT)
995 abort ();
996
997 adjust_overlays_for_insert (PT, nchars);
998 adjust_markers_for_insert (PT, PT_BYTE,
999 PT + nchars, PT_BYTE + nbytes,
1000 combined_before_bytes, combined_after_bytes,
1001 before_markers);
1002
1003 #ifdef USE_TEXT_PROPERTIES
1004 if (BUF_INTERVALS (current_buffer) != 0)
1005 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
1006 offset_intervals (current_buffer, PT, nchars);
1007
1008 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
1009 Fset_text_properties (make_number (PT), make_number (PT + nchars),
1010 Qnil, Qnil);
1011 #endif
1012
1013 {
1014 int pos = PT, pos_byte = PT_BYTE;
1015
1016 adjust_point (nchars + combined_after_bytes,
1017 nbytes + combined_after_bytes);
1018
1019 if (combined_after_bytes)
1020 combine_bytes (pos + nchars, pos_byte + nbytes, combined_after_bytes);
1021
1022 if (combined_before_bytes)
1023 combine_bytes (pos, pos_byte, combined_before_bytes);
1024 }
1025 }
1026 \f
1027 /* Insert the part of the text of STRING, a Lisp object assumed to be
1028 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1029 starting at position POS / POS_BYTE. If the text of STRING has properties,
1030 copy them into the buffer.
1031
1032 It does not work to use `insert' for this, because a GC could happen
1033 before we bcopy the stuff into the buffer, and relocate the string
1034 without insert noticing. */
1035
1036 void
1037 insert_from_string (string, pos, pos_byte, length, length_byte, inherit)
1038 Lisp_Object string;
1039 register int pos, pos_byte, length, length_byte;
1040 int inherit;
1041 {
1042 if (length > 0)
1043 {
1044 int opoint = PT;
1045 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1046 inherit, 0);
1047 signal_after_change (opoint, 0, PT - opoint);
1048 }
1049 }
1050
1051 /* Like `insert_from_string' except that all markers pointing
1052 at the place where the insertion happens are adjusted to point after it. */
1053
1054 void
1055 insert_from_string_before_markers (string, pos, pos_byte,
1056 length, length_byte, inherit)
1057 Lisp_Object string;
1058 register int pos, pos_byte, length, length_byte;
1059 int inherit;
1060 {
1061 if (length > 0)
1062 {
1063 int opoint = PT;
1064 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1065 inherit, 1);
1066 signal_after_change (opoint, 0, PT - opoint);
1067 }
1068 }
1069
1070 /* Subroutine of the insertion functions above. */
1071
1072 static void
1073 insert_from_string_1 (string, pos, pos_byte, nchars, nbytes,
1074 inherit, before_markers)
1075 Lisp_Object string;
1076 register int pos, pos_byte, nchars, nbytes;
1077 int inherit, before_markers;
1078 {
1079 register Lisp_Object temp;
1080 struct gcpro gcpro1;
1081 int outgoing_nbytes = nbytes;
1082 int combined_before_bytes, combined_after_bytes;
1083 int adjusted_nchars;
1084 INTERVAL intervals;
1085 Lisp_Object deletion;
1086
1087 /* Make OUTGOING_NBYTES describe the text
1088 as it will be inserted in this buffer. */
1089
1090 if (NILP (current_buffer->enable_multibyte_characters))
1091 outgoing_nbytes = nchars;
1092 else if (nchars == nbytes)
1093 outgoing_nbytes
1094 = count_size_as_multibyte (&XSTRING (string)->data[pos_byte],
1095 nbytes);
1096
1097 /* Make sure point-max won't overflow after this insertion. */
1098 XSETINT (temp, outgoing_nbytes + Z);
1099 if (outgoing_nbytes + Z != XINT (temp))
1100 error ("Maximum buffer size exceeded");
1101
1102 GCPRO1 (string);
1103 prepare_to_modify_buffer (PT, PT, NULL);
1104
1105 if (PT != GPT)
1106 move_gap_both (PT, PT_BYTE);
1107 if (GAP_SIZE < nbytes)
1108 make_gap (outgoing_nbytes - GAP_SIZE);
1109 UNGCPRO;
1110
1111 /* Copy the string text into the buffer, perhaps converting
1112 between single-byte and multibyte. */
1113 copy_text (XSTRING (string)->data + pos_byte, GPT_ADDR, nbytes,
1114 /* If these are equal, it is a single-byte string.
1115 Its chars are either ASCII, in which case copy_text
1116 won't change it, or single-byte non-ASCII chars,
1117 that need to be changed. */
1118 nchars != nbytes,
1119 ! NILP (current_buffer->enable_multibyte_characters));
1120
1121 /* We have copied text into the gap, but we have not altered
1122 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1123 to these functions and get the same results as we would
1124 have got earlier on. Meanwhile, PT_ADDR does point to
1125 the text that has been stored by copy_text. */
1126
1127 combined_before_bytes
1128 = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1129 combined_after_bytes
1130 = count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1131
1132 /* Record deletion of the surrounding text that combines with
1133 the insertion. This, together with recording the insertion,
1134 will add up to the right stuff in the undo list.
1135
1136 But there is no need to actually delete the combining bytes
1137 from the buffer and reinsert them. */
1138
1139 if (combined_after_bytes)
1140 {
1141 deletion = make_buffer_string_both (PT, PT_BYTE,
1142 PT + combined_after_bytes,
1143 PT_BYTE + combined_after_bytes, 1);
1144
1145 adjust_markers_for_record_delete (PT, PT_BYTE,
1146 PT + combined_after_bytes,
1147 PT_BYTE + combined_after_bytes);
1148 record_delete (PT, deletion);
1149 }
1150
1151 if (combined_before_bytes)
1152 {
1153 deletion = make_buffer_string_both (PT - 1, CHAR_TO_BYTE (PT - 1),
1154 PT, PT_BYTE, 1);
1155 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
1156 PT, PT_BYTE);
1157 record_delete (PT - 1, deletion);
1158 }
1159
1160 record_insert (PT - !!combined_before_bytes,
1161 nchars - combined_before_bytes + !!combined_before_bytes);
1162 MODIFF++;
1163
1164 GAP_SIZE -= outgoing_nbytes;
1165 GPT += nchars;
1166 ZV += nchars;
1167 Z += nchars;
1168 GPT_BYTE += outgoing_nbytes;
1169 ZV_BYTE += outgoing_nbytes;
1170 Z_BYTE += outgoing_nbytes;
1171 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1172
1173 if (combined_after_bytes)
1174 move_gap_both (GPT + combined_after_bytes,
1175 GPT_BYTE + combined_after_bytes);
1176
1177 if (GPT_BYTE < GPT)
1178 abort ();
1179
1180 adjust_overlays_for_insert (PT, nchars);
1181 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1182 PT_BYTE + outgoing_nbytes,
1183 combined_before_bytes, combined_after_bytes,
1184 before_markers);
1185
1186 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1187 offset_intervals (current_buffer, PT, nchars);
1188
1189 intervals = XSTRING (string)->intervals;
1190 /* Get the intervals for the part of the string we are inserting--
1191 not including the combined-before bytes. */
1192 if (nbytes < XSTRING (string)->size_byte)
1193 intervals = copy_intervals (intervals, pos, nchars);
1194
1195 /* Insert those intervals. */
1196 graft_intervals_into_buffer (intervals, PT, nchars,
1197 current_buffer, inherit);
1198
1199 {
1200 int pos = PT, pos_byte = PT_BYTE;
1201
1202 adjust_point (nchars + combined_after_bytes,
1203 outgoing_nbytes + combined_after_bytes);
1204
1205 if (combined_after_bytes)
1206 combine_bytes (pos + nchars, pos_byte + outgoing_nbytes,
1207 combined_after_bytes);
1208
1209 if (combined_before_bytes)
1210 combine_bytes (pos, pos_byte, combined_before_bytes);
1211 }
1212 }
1213 \f
1214 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1215 current buffer. If the text in BUF has properties, they are absorbed
1216 into the current buffer.
1217
1218 It does not work to use `insert' for this, because a malloc could happen
1219 and relocate BUF's text before the bcopy happens. */
1220
1221 void
1222 insert_from_buffer (buf, charpos, nchars, inherit)
1223 struct buffer *buf;
1224 int charpos, nchars;
1225 int inherit;
1226 {
1227 if (nchars > 0)
1228 {
1229 int opoint = PT;
1230
1231 insert_from_buffer_1 (buf, charpos, nchars, inherit);
1232 signal_after_change (opoint, 0, PT - opoint);
1233 }
1234 }
1235
1236 static void
1237 insert_from_buffer_1 (buf, from, nchars, inherit)
1238 struct buffer *buf;
1239 int from, nchars;
1240 int inherit;
1241 {
1242 register Lisp_Object temp, deletion;
1243 int chunk;
1244 int from_byte = buf_charpos_to_bytepos (buf, from);
1245 int to_byte = buf_charpos_to_bytepos (buf, from + nchars);
1246 int incoming_nbytes = to_byte - from_byte;
1247 int outgoing_nbytes = incoming_nbytes;
1248 int combined_before_bytes, combined_after_bytes;
1249 int adjusted_nchars;
1250 INTERVAL intervals;
1251
1252 /* Make OUTGOING_NBYTES describe the text
1253 as it will be inserted in this buffer. */
1254
1255 if (NILP (current_buffer->enable_multibyte_characters))
1256 outgoing_nbytes = nchars;
1257 else if (NILP (buf->enable_multibyte_characters))
1258 outgoing_nbytes
1259 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf, from_byte),
1260 incoming_nbytes);
1261
1262 /* Make sure point-max won't overflow after this insertion. */
1263 XSETINT (temp, outgoing_nbytes + Z);
1264 if (outgoing_nbytes + Z != XINT (temp))
1265 error ("Maximum buffer size exceeded");
1266
1267 prepare_to_modify_buffer (PT, PT, NULL);
1268
1269 if (PT != GPT)
1270 move_gap_both (PT, PT_BYTE);
1271 if (GAP_SIZE < outgoing_nbytes)
1272 make_gap (outgoing_nbytes - GAP_SIZE);
1273
1274 if (from < BUF_GPT (buf))
1275 {
1276 chunk = BUF_GPT_BYTE (buf) - from_byte;
1277 if (chunk > incoming_nbytes)
1278 chunk = incoming_nbytes;
1279 copy_text (BUF_BYTE_ADDRESS (buf, from_byte),
1280 GPT_ADDR, chunk,
1281 ! NILP (buf->enable_multibyte_characters),
1282 ! NILP (current_buffer->enable_multibyte_characters));
1283 }
1284 else
1285 chunk = 0;
1286 if (chunk < incoming_nbytes)
1287 copy_text (BUF_BYTE_ADDRESS (buf, from_byte + chunk),
1288 GPT_ADDR + chunk, incoming_nbytes - chunk,
1289 ! NILP (buf->enable_multibyte_characters),
1290 ! NILP (current_buffer->enable_multibyte_characters));
1291
1292 /* We have copied text into the gap, but we have not altered
1293 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1294 to these functions and get the same results as we would
1295 have got earlier on. Meanwhile, GPT_ADDR does point to
1296 the text that has been stored by copy_text. */
1297 combined_before_bytes
1298 = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1299 combined_after_bytes
1300 = count_combining_after (GPT_ADDR, outgoing_nbytes,
1301 PT, PT_BYTE);
1302
1303 /* Record deletion of the surrounding text that combines with
1304 the insertion. This, together with recording the insertion,
1305 will add up to the right stuff in the undo list.
1306
1307 But there is no need to actually delete the combining bytes
1308 from the buffer and reinsert them. */
1309
1310 if (combined_after_bytes)
1311 {
1312 deletion = make_buffer_string_both (PT, PT_BYTE,
1313 PT + combined_after_bytes,
1314 PT_BYTE + combined_after_bytes, 1);
1315
1316 adjust_markers_for_record_delete (PT, PT_BYTE,
1317 PT + combined_after_bytes,
1318 PT_BYTE + combined_after_bytes);
1319 record_delete (PT, deletion);
1320 }
1321
1322 if (combined_before_bytes)
1323 {
1324 deletion = make_buffer_string_both (PT - 1, CHAR_TO_BYTE (PT - 1),
1325 PT, PT_BYTE, 1);
1326 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
1327 PT, PT_BYTE);
1328 record_delete (PT - 1, deletion);
1329 }
1330
1331 record_insert (PT - !!combined_before_bytes,
1332 nchars - combined_before_bytes + !!combined_before_bytes);
1333 MODIFF++;
1334
1335 GAP_SIZE -= outgoing_nbytes;
1336 GPT += nchars;
1337 ZV += nchars;
1338 Z += nchars;
1339 GPT_BYTE += outgoing_nbytes;
1340 ZV_BYTE += outgoing_nbytes;
1341 Z_BYTE += outgoing_nbytes;
1342 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1343
1344 if (combined_after_bytes)
1345 move_gap_both (GPT + combined_after_bytes,
1346 GPT_BYTE + combined_after_bytes);
1347
1348 if (GPT_BYTE < GPT)
1349 abort ();
1350
1351 adjust_overlays_for_insert (PT, nchars);
1352 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1353 PT_BYTE + outgoing_nbytes,
1354 combined_before_bytes, combined_after_bytes, 0);
1355
1356 #ifdef USE_TEXT_PROPERTIES
1357 if (BUF_INTERVALS (current_buffer) != 0)
1358 offset_intervals (current_buffer, PT, nchars);
1359 #endif
1360
1361 /* Get the intervals for the part of the string we are inserting--
1362 not including the combined-before bytes. */
1363 intervals = BUF_INTERVALS (buf);
1364 if (outgoing_nbytes < BUF_Z_BYTE (buf) - BUF_BEG_BYTE (buf))
1365 intervals = copy_intervals (intervals, from, nchars);
1366
1367 /* Insert those intervals. */
1368 graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
1369
1370 {
1371 int pos = PT, pos_byte = PT_BYTE;
1372
1373 adjust_point (nchars + combined_after_bytes,
1374 outgoing_nbytes + combined_after_bytes);
1375
1376 if (combined_after_bytes)
1377 combine_bytes (pos + nchars, pos_byte + outgoing_nbytes,
1378 combined_after_bytes);
1379
1380 if (combined_before_bytes)
1381 combine_bytes (pos, pos_byte, combined_before_bytes);
1382 }
1383 }
1384 \f
1385 /* This function should be called after moving gap to FROM and before
1386 altering text between FROM and TO. This adjusts various position
1387 keepers and markers as if the text is deleted. Don't forget to
1388 call adjust_after_replace after you actually alter the text. */
1389
1390 void
1391 adjust_before_replace (from, from_byte, to, to_byte)
1392 int from, from_byte, to, to_byte;
1393 {
1394 Lisp_Object deletion;
1395 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1396
1397 adjust_markers_for_delete (from, from_byte, to, to_byte);
1398 record_delete (from, deletion);
1399 adjust_overlays_for_delete (from, to - from);
1400 }
1401
1402 /* This function should be called after altering the text between FROM
1403 and TO to a new text of LEN chars (LEN_BYTE bytes), but before
1404 making the text a buffer contents. It exists just after GPT_ADDR. */
1405
1406 void
1407 adjust_after_replace (from, from_byte, to, to_byte, len, len_byte, replace)
1408 int from, from_byte, to, to_byte, len, len_byte, replace;
1409 {
1410 int combined_before_bytes
1411 = count_combining_before (GPT_ADDR, len_byte, from, from_byte);
1412 int combined_after_bytes
1413 = count_combining_after (GPT_ADDR, len_byte, from, from_byte);
1414 Lisp_Object deletion;
1415
1416 if (combined_after_bytes)
1417 {
1418 deletion = make_buffer_string_both (from, from_byte,
1419 from + combined_after_bytes,
1420 from_byte + combined_after_bytes, 1);
1421
1422 adjust_markers_for_record_delete (from, from_byte,
1423 from + combined_after_bytes,
1424 from_byte + combined_after_bytes);
1425 record_delete (from, deletion);
1426 }
1427
1428 if (combined_before_bytes)
1429 {
1430 deletion = make_buffer_string_both (from - 1, CHAR_TO_BYTE (from - 1),
1431 from, from_byte, 1);
1432 adjust_markers_for_record_delete (from - 1, CHAR_TO_BYTE (from - 1),
1433 from, from_byte);
1434 record_delete (from - 1, deletion);
1435 }
1436
1437 /* Update various buffer positions for the new text. */
1438 GAP_SIZE -= len_byte;
1439 ZV += len; Z+= len;
1440 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1441 GPT += len; GPT_BYTE += len_byte;
1442 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1443
1444 if (combined_after_bytes)
1445 move_gap_both (GPT + combined_after_bytes,
1446 GPT_BYTE + combined_after_bytes);
1447
1448 record_insert (from - !!combined_before_bytes,
1449 len - combined_before_bytes + !!combined_before_bytes);
1450 adjust_overlays_for_insert (from, len);
1451 adjust_markers_for_insert (from, from_byte,
1452 from + len, from_byte + len_byte,
1453 combined_before_bytes, combined_after_bytes, 0);
1454 #ifdef USE_TEXT_PROPERTIES
1455 if (BUF_INTERVALS (current_buffer) != 0)
1456 /* REPLACE zero means that we have not yet adjusted the interval
1457 tree for the text between FROM and TO, thus, we must treat the
1458 new text as a newly inserted text, not as a replacement of
1459 something. */
1460 offset_intervals (current_buffer, from, len - (replace ? to - from : 0));
1461 #endif
1462
1463 {
1464 int pos = PT, pos_byte = PT_BYTE;
1465
1466 if (from < PT)
1467 adjust_point (len - (to - from) + combined_after_bytes,
1468 len_byte - (to_byte - from_byte) + combined_after_bytes);
1469 else if (from == PT && combined_before_bytes)
1470 adjust_point (0, combined_before_bytes);
1471
1472 if (combined_after_bytes)
1473 combine_bytes (from + len, from_byte + len_byte, combined_after_bytes);
1474
1475 if (combined_before_bytes)
1476 combine_bytes (from, from_byte, combined_before_bytes);
1477 }
1478
1479 if (len == 0)
1480 evaporate_overlays (from);
1481 MODIFF++;
1482 }
1483
1484 /* Replace the text from character positions FROM to TO with NEW,
1485 If PREPARE is nonzero, call prepare_to_modify_buffer.
1486 If INHERIT, the newly inserted text should inherit text properties
1487 from the surrounding non-deleted text. */
1488
1489 /* Note that this does not yet handle markers quite right.
1490 Also it needs to record a single undo-entry that does a replacement
1491 rather than a separate delete and insert.
1492 That way, undo will also handle markers properly. */
1493
1494 void
1495 replace_range (from, to, new, prepare, inherit)
1496 Lisp_Object new;
1497 int from, to, prepare, inherit;
1498 {
1499 int inschars = XSTRING (new)->size;
1500 int insbytes = XSTRING (new)->size_byte;
1501 int from_byte, to_byte;
1502 int nbytes_del, nchars_del;
1503 register Lisp_Object temp;
1504 struct gcpro gcpro1;
1505 int combined_before_bytes, combined_after_bytes;
1506 int adjusted_inschars;
1507 INTERVAL intervals;
1508 int outgoing_insbytes = insbytes;
1509 Lisp_Object deletion;
1510
1511 GCPRO1 (new);
1512
1513 if (prepare)
1514 {
1515 int range_length = to - from;
1516 prepare_to_modify_buffer (from, to, &from);
1517 to = from + range_length;
1518 }
1519
1520 UNGCPRO;
1521
1522 /* Make args be valid */
1523 if (from < BEGV)
1524 from = BEGV;
1525 if (to > ZV)
1526 to = ZV;
1527
1528 from_byte = CHAR_TO_BYTE (from);
1529 to_byte = CHAR_TO_BYTE (to);
1530
1531 nchars_del = to - from;
1532 nbytes_del = to_byte - from_byte;
1533
1534 if (nbytes_del <= 0 && insbytes == 0)
1535 return;
1536
1537 /* Make OUTGOING_INSBYTES describe the text
1538 as it will be inserted in this buffer. */
1539
1540 if (NILP (current_buffer->enable_multibyte_characters))
1541 outgoing_insbytes = inschars;
1542 else if (inschars == insbytes)
1543 outgoing_insbytes
1544 = count_size_as_multibyte (XSTRING (new)->data, insbytes);
1545
1546 /* Make sure point-max won't overflow after this insertion. */
1547 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1548 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1549 error ("Maximum buffer size exceeded");
1550
1551 GCPRO1 (new);
1552
1553 /* Make sure the gap is somewhere in or next to what we are deleting. */
1554 if (from > GPT)
1555 gap_right (from, from_byte);
1556 if (to < GPT)
1557 gap_left (to, to_byte, 0);
1558
1559 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1560
1561 /* Relocate all markers pointing into the new, larger gap
1562 to point at the end of the text before the gap.
1563 Do this before recording the deletion,
1564 so that undo handles this after reinserting the text. */
1565 adjust_markers_for_delete (from, from_byte, to, to_byte);
1566
1567 record_delete (from, deletion);
1568
1569 GAP_SIZE += nbytes_del;
1570 ZV -= nchars_del;
1571 Z -= nchars_del;
1572 ZV_BYTE -= nbytes_del;
1573 Z_BYTE -= nbytes_del;
1574 GPT = from;
1575 GPT_BYTE = from_byte;
1576 *(GPT_ADDR) = 0; /* Put an anchor. */
1577
1578 if (GPT_BYTE < GPT)
1579 abort ();
1580
1581 if (GPT - BEG < beg_unchanged)
1582 beg_unchanged = GPT - BEG;
1583 if (Z - GPT < end_unchanged)
1584 end_unchanged = Z - GPT;
1585
1586 if (GAP_SIZE < insbytes)
1587 make_gap (insbytes - GAP_SIZE);
1588
1589 /* Copy the string text into the buffer, perhaps converting
1590 between single-byte and multibyte. */
1591 copy_text (XSTRING (new)->data, GPT_ADDR, insbytes,
1592 /* If these are equal, it is a single-byte string.
1593 Its chars are either ASCII, in which case copy_text
1594 won't change it, or single-byte non-ASCII chars,
1595 that need to be changed. */
1596 inschars != insbytes,
1597 ! NILP (current_buffer->enable_multibyte_characters));
1598
1599 /* We have copied text into the gap, but we have not altered
1600 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1601 to these functions and get the same results as we would
1602 have got earlier on. Meanwhile, GPT_ADDR does point to
1603 the text that has been stored by copy_text. */
1604
1605 combined_before_bytes
1606 = count_combining_before (GPT_ADDR, outgoing_insbytes, PT, PT_BYTE);
1607 combined_after_bytes
1608 = count_combining_after (GPT_ADDR, outgoing_insbytes, PT, PT_BYTE);
1609
1610 /* Record deletion of the surrounding text that combines with
1611 the insertion. This, together with recording the insertion,
1612 will add up to the right stuff in the undo list.
1613
1614 But there is no need to actually delete the combining bytes
1615 from the buffer and reinsert them. */
1616
1617 if (combined_after_bytes)
1618 {
1619 deletion = make_buffer_string_both (PT, PT_BYTE,
1620 PT + combined_after_bytes,
1621 PT_BYTE + combined_after_bytes, 1);
1622
1623 adjust_markers_for_record_delete (PT, PT_BYTE,
1624 PT + combined_after_bytes,
1625 PT_BYTE + combined_after_bytes);
1626 record_delete (PT, deletion);
1627 }
1628
1629 if (combined_before_bytes)
1630 {
1631 deletion = make_buffer_string_both (PT - 1, CHAR_TO_BYTE (PT - 1),
1632 PT, PT_BYTE, 1);
1633 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
1634 PT, PT_BYTE);
1635 record_delete (PT - 1, deletion);
1636 }
1637
1638 record_insert (PT - !!combined_before_bytes,
1639 inschars - combined_before_bytes + !!combined_before_bytes);
1640
1641 GAP_SIZE -= outgoing_insbytes;
1642 GPT += inschars;
1643 ZV += inschars;
1644 Z += inschars;
1645 GPT_BYTE += outgoing_insbytes;
1646 ZV_BYTE += outgoing_insbytes;
1647 Z_BYTE += outgoing_insbytes;
1648 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1649
1650 if (combined_after_bytes)
1651 move_gap_both (GPT + combined_after_bytes,
1652 GPT_BYTE + combined_after_bytes);
1653
1654 if (GPT_BYTE < GPT)
1655 abort ();
1656
1657 /* Adjust the overlay center as needed. This must be done after
1658 adjusting the markers that bound the overlays. */
1659 adjust_overlays_for_delete (from, nchars_del);
1660 adjust_overlays_for_insert (from, inschars);
1661 adjust_markers_for_insert (from, from_byte,
1662 from + inschars, from_byte + outgoing_insbytes,
1663 combined_before_bytes, combined_after_bytes, 0);
1664
1665 #ifdef USE_TEXT_PROPERTIES
1666 offset_intervals (current_buffer, PT, inschars - nchars_del);
1667
1668 /* Get the intervals for the part of the string we are inserting--
1669 not including the combined-before bytes. */
1670 intervals = XSTRING (new)->intervals;
1671 /* Insert those intervals. */
1672 graft_intervals_into_buffer (intervals, from, inschars,
1673 current_buffer, inherit);
1674 #endif
1675
1676 /* Relocate point as if it were a marker. */
1677 if (from < PT)
1678 adjust_point ((from + inschars - (PT < to ? PT : to)
1679 + combined_after_bytes),
1680 (from_byte + outgoing_insbytes
1681 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)
1682 + combined_after_bytes));
1683
1684 if (combined_after_bytes)
1685 combine_bytes (from + inschars, from_byte + outgoing_insbytes,
1686 combined_after_bytes);
1687
1688 if (combined_before_bytes)
1689 combine_bytes (from, from_byte, combined_before_bytes);
1690
1691 if (outgoing_insbytes == 0)
1692 evaporate_overlays (from);
1693
1694 MODIFF++;
1695 UNGCPRO;
1696
1697 signal_after_change (from, nchars_del, PT - from);
1698 }
1699 \f
1700 /* Delete characters in current buffer
1701 from FROM up to (but not including) TO.
1702 If TO comes before FROM, we delete nothing. */
1703
1704 void
1705 del_range (from, to)
1706 register int from, to;
1707 {
1708 del_range_1 (from, to, 1);
1709 }
1710
1711 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
1712
1713 void
1714 del_range_1 (from, to, prepare)
1715 int from, to, prepare;
1716 {
1717 int from_byte, to_byte;
1718
1719 /* Make args be valid */
1720 if (from < BEGV)
1721 from = BEGV;
1722 if (to > ZV)
1723 to = ZV;
1724
1725 if (to <= from)
1726 return;
1727
1728 if (prepare)
1729 {
1730 int range_length = to - from;
1731 prepare_to_modify_buffer (from, to, &from);
1732 to = from + range_length;
1733 }
1734
1735 from_byte = CHAR_TO_BYTE (from);
1736 to_byte = CHAR_TO_BYTE (to);
1737
1738 del_range_2 (from, from_byte, to, to_byte);
1739 }
1740
1741 /* Like del_range_1 but args are byte positions, not char positions. */
1742
1743 void
1744 del_range_byte (from_byte, to_byte, prepare)
1745 int from_byte, to_byte, prepare;
1746 {
1747 int from, to;
1748
1749 /* Make args be valid */
1750 if (from_byte < BEGV_BYTE)
1751 from_byte = BEGV_BYTE;
1752 if (to_byte > ZV_BYTE)
1753 to_byte = ZV_BYTE;
1754
1755 if (to_byte <= from_byte)
1756 return;
1757
1758 from = BYTE_TO_CHAR (from_byte);
1759 to = BYTE_TO_CHAR (to_byte);
1760
1761 if (prepare)
1762 {
1763 int old_from = from, old_to = Z - to;
1764 int range_length = to - from;
1765 prepare_to_modify_buffer (from, to, &from);
1766 to = from + range_length;
1767
1768 if (old_from != from)
1769 from_byte = CHAR_TO_BYTE (from);
1770 if (old_to == Z - to)
1771 to_byte = CHAR_TO_BYTE (to);
1772 }
1773
1774 del_range_2 (from, from_byte, to, to_byte);
1775 }
1776
1777 /* Like del_range_1, but positions are specified both as charpos
1778 and bytepos. */
1779
1780 void
1781 del_range_both (from, from_byte, to, to_byte, prepare)
1782 int from, from_byte, to, to_byte, prepare;
1783 {
1784 /* Make args be valid */
1785 if (from_byte < BEGV_BYTE)
1786 from_byte = BEGV_BYTE;
1787 if (to_byte > ZV_BYTE)
1788 to_byte = ZV_BYTE;
1789
1790 if (to_byte <= from_byte)
1791 return;
1792
1793 if (from < BEGV)
1794 from = BEGV;
1795 if (to > ZV)
1796 to = ZV;
1797
1798 if (prepare)
1799 {
1800 int old_from = from, old_to = Z - to;
1801 int range_length = to - from;
1802 prepare_to_modify_buffer (from, to, &from);
1803 to = from + range_length;
1804
1805 if (old_from != from)
1806 from_byte = CHAR_TO_BYTE (from);
1807 if (old_to == Z - to)
1808 to_byte = CHAR_TO_BYTE (to);
1809 }
1810
1811 del_range_2 (from, from_byte, to, to_byte);
1812 }
1813
1814 /* Delete a range of text, specified both as character positions
1815 and byte positions. FROM and TO are character positions,
1816 while FROM_BYTE and TO_BYTE are byte positions. */
1817
1818 void
1819 del_range_2 (from, from_byte, to, to_byte)
1820 int from, from_byte, to, to_byte;
1821 {
1822 register int nbytes_del, nchars_del;
1823 int combined_after_bytes;
1824 Lisp_Object deletion;
1825 int from_byte_1;
1826
1827 nchars_del = to - from;
1828 nbytes_del = to_byte - from_byte;
1829
1830 /* Make sure the gap is somewhere in or next to what we are deleting. */
1831 if (from > GPT)
1832 gap_right (from, from_byte);
1833 if (to < GPT)
1834 gap_left (to, to_byte, 0);
1835
1836 combined_after_bytes
1837 = count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte),
1838 ZV_BYTE - to_byte, from, from_byte);
1839 if (combined_after_bytes)
1840 {
1841 from_byte_1 = from_byte;
1842 DEC_POS (from_byte_1);
1843 }
1844 else
1845 from_byte_1 = from_byte;
1846
1847 deletion
1848 = make_buffer_string_both (from - !!combined_after_bytes,
1849 from_byte_1,
1850 to + combined_after_bytes,
1851 to_byte + combined_after_bytes, 1);
1852
1853 /* Relocate all markers pointing into the new, larger gap
1854 to point at the end of the text before the gap.
1855 Do this before recording the deletion,
1856 so that undo handles this after reinserting the text. */
1857 adjust_markers_for_delete (from, from_byte, to, to_byte);
1858 if (combined_after_bytes)
1859 {
1860 /* Adjust markers for the phony deletion
1861 that we are about to call record_undo for. */
1862
1863 /* Here we delete the markers that formerly
1864 pointed at TO ... TO + COMBINED_AFTER_BYTES.
1865 But because of the call to adjust_markers_for_delete, above,
1866 they now point at FROM ... FROM + COMBINED_AFTER_BYTES. */
1867 adjust_markers_for_record_delete (from, from_byte,
1868 from + combined_after_bytes,
1869 from_byte + combined_after_bytes);
1870
1871 adjust_markers_for_record_delete (from - 1, from_byte_1,
1872 from, from_byte);
1873 }
1874 record_delete (from - !!combined_after_bytes, deletion);
1875
1876 if (combined_after_bytes)
1877 /* COMBINED_AFTER_BYTES nonzero means that the above record_delete
1878 moved the gap by calling Fbuffer_substring. We must move the
1879 gap again to a proper place. */
1880 move_gap_both (from, from_byte);
1881 MODIFF++;
1882
1883 /* Relocate point as if it were a marker. */
1884 if (from < PT)
1885 adjust_point (from - (PT < to ? PT : to),
1886 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte));
1887
1888 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1889 offset_intervals (current_buffer, from, - nchars_del);
1890
1891 /* Adjust the overlay center as needed. This must be done after
1892 adjusting the markers that bound the overlays. */
1893 adjust_overlays_for_delete (from, nchars_del);
1894
1895 GAP_SIZE += nbytes_del;
1896 ZV_BYTE -= nbytes_del;
1897 Z_BYTE -= nbytes_del;
1898 ZV -= nchars_del;
1899 Z -= nchars_del;
1900 GPT = from;
1901 GPT_BYTE = from_byte;
1902
1903 if (combined_after_bytes)
1904 move_gap_both (GPT + combined_after_bytes,
1905 GPT_BYTE + combined_after_bytes);
1906
1907 *(GPT_ADDR) = 0; /* Put an anchor. */
1908
1909 if (GPT_BYTE < GPT)
1910 abort ();
1911
1912 if (GPT - BEG < beg_unchanged)
1913 beg_unchanged = GPT - BEG;
1914 if (Z - GPT < end_unchanged)
1915 end_unchanged = Z - GPT;
1916
1917 if (combined_after_bytes)
1918 {
1919 combine_bytes (from, from_byte, combined_after_bytes);
1920
1921 record_insert (GPT - 1, 1);
1922 }
1923
1924 evaporate_overlays (from);
1925 signal_after_change (from, nchars_del, 0);
1926 }
1927 \f
1928 /* Call this if you're about to change the region of BUFFER from
1929 character positions START to END. This checks the read-only
1930 properties of the region, calls the necessary modification hooks,
1931 and warns the next redisplay that it should pay attention to that
1932 area. */
1933
1934 void
1935 modify_region (buffer, start, end)
1936 struct buffer *buffer;
1937 int start, end;
1938 {
1939 struct buffer *old_buffer = current_buffer;
1940
1941 if (buffer != old_buffer)
1942 set_buffer_internal (buffer);
1943
1944 prepare_to_modify_buffer (start, end, NULL);
1945
1946 if (start - 1 < beg_unchanged
1947 || (unchanged_modified == MODIFF
1948 && overlay_unchanged_modified == OVERLAY_MODIFF))
1949 beg_unchanged = start - 1;
1950 if (Z - end < end_unchanged
1951 || (unchanged_modified == MODIFF
1952 && overlay_unchanged_modified == OVERLAY_MODIFF))
1953 end_unchanged = Z - end;
1954
1955 if (MODIFF <= SAVE_MODIFF)
1956 record_first_change ();
1957 MODIFF++;
1958
1959 buffer->point_before_scroll = Qnil;
1960
1961 if (buffer != old_buffer)
1962 set_buffer_internal (old_buffer);
1963 }
1964 \f
1965 /* Check that it is okay to modify the buffer between START and END,
1966 which are char positions.
1967
1968 Run the before-change-function, if any. If intervals are in use,
1969 verify that the text to be modified is not read-only, and call
1970 any modification properties the text may have.
1971
1972 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1973 by holding its value temporarily in a marker. */
1974
1975 void
1976 prepare_to_modify_buffer (start, end, preserve_ptr)
1977 int start, end;
1978 int *preserve_ptr;
1979 {
1980 if (!NILP (current_buffer->read_only))
1981 Fbarf_if_buffer_read_only ();
1982
1983 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1984 if (BUF_INTERVALS (current_buffer) != 0)
1985 {
1986 if (preserve_ptr)
1987 {
1988 Lisp_Object preserve_marker;
1989 struct gcpro gcpro1;
1990 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
1991 GCPRO1 (preserve_marker);
1992 verify_interval_modification (current_buffer, start, end);
1993 *preserve_ptr = marker_position (preserve_marker);
1994 unchain_marker (preserve_marker);
1995 UNGCPRO;
1996 }
1997 else
1998 verify_interval_modification (current_buffer, start, end);
1999 }
2000
2001 #ifdef CLASH_DETECTION
2002 if (!NILP (current_buffer->file_truename)
2003 /* Make binding buffer-file-name to nil effective. */
2004 && !NILP (current_buffer->filename)
2005 && SAVE_MODIFF >= MODIFF)
2006 lock_file (current_buffer->file_truename);
2007 #else
2008 /* At least warn if this file has changed on disk since it was visited. */
2009 if (!NILP (current_buffer->filename)
2010 && SAVE_MODIFF >= MODIFF
2011 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2012 && !NILP (Ffile_exists_p (current_buffer->filename)))
2013 call1 (intern ("ask-user-about-supersession-threat"),
2014 current_buffer->filename);
2015 #endif /* not CLASH_DETECTION */
2016
2017 signal_before_change (start, end, preserve_ptr);
2018
2019 if (current_buffer->newline_cache)
2020 invalidate_region_cache (current_buffer,
2021 current_buffer->newline_cache,
2022 start - BEG, Z - end);
2023 if (current_buffer->width_run_cache)
2024 invalidate_region_cache (current_buffer,
2025 current_buffer->width_run_cache,
2026 start - BEG, Z - end);
2027
2028 Vdeactivate_mark = Qt;
2029 }
2030 \f
2031 /* These macros work with an argument named `preserve_ptr'
2032 and a local variable named `preserve_marker'. */
2033
2034 #define PRESERVE_VALUE \
2035 if (preserve_ptr && NILP (preserve_marker)) \
2036 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2037
2038 #define RESTORE_VALUE \
2039 if (! NILP (preserve_marker)) \
2040 { \
2041 *preserve_ptr = marker_position (preserve_marker); \
2042 unchain_marker (preserve_marker); \
2043 }
2044
2045 #define PRESERVE_START_END \
2046 if (NILP (start_marker)) \
2047 start_marker = Fcopy_marker (start, Qnil); \
2048 if (NILP (end_marker)) \
2049 end_marker = Fcopy_marker (end, Qnil);
2050
2051 #define FETCH_START \
2052 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2053
2054 #define FETCH_END \
2055 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2056
2057 /* Signal a change to the buffer immediately before it happens.
2058 START_INT and END_INT are the bounds of the text to be changed.
2059
2060 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2061 by holding its value temporarily in a marker. */
2062
2063 void
2064 signal_before_change (start_int, end_int, preserve_ptr)
2065 int start_int, end_int;
2066 int *preserve_ptr;
2067 {
2068 Lisp_Object start, end;
2069 Lisp_Object start_marker, end_marker;
2070 Lisp_Object preserve_marker;
2071 struct gcpro gcpro1, gcpro2, gcpro3;
2072
2073 start = make_number (start_int);
2074 end = make_number (end_int);
2075 preserve_marker = Qnil;
2076 start_marker = Qnil;
2077 end_marker = Qnil;
2078 GCPRO3 (preserve_marker, start_marker, end_marker);
2079
2080 /* If buffer is unmodified, run a special hook for that case. */
2081 if (SAVE_MODIFF >= MODIFF
2082 && !NILP (Vfirst_change_hook)
2083 && !NILP (Vrun_hooks))
2084 {
2085 PRESERVE_VALUE;
2086 PRESERVE_START_END;
2087 call1 (Vrun_hooks, Qfirst_change_hook);
2088 }
2089
2090 /* Run the before-change-function if any.
2091 We don't bother "binding" this variable to nil
2092 because it is obsolete anyway and new code should not use it. */
2093 if (!NILP (Vbefore_change_function))
2094 {
2095 PRESERVE_VALUE;
2096 PRESERVE_START_END;
2097 call2 (Vbefore_change_function, FETCH_START, FETCH_END);
2098 }
2099
2100 /* Now run the before-change-functions if any. */
2101 if (!NILP (Vbefore_change_functions))
2102 {
2103 Lisp_Object args[3];
2104 Lisp_Object before_change_functions;
2105 Lisp_Object after_change_functions;
2106 struct gcpro gcpro1, gcpro2;
2107
2108 PRESERVE_VALUE;
2109 PRESERVE_START_END;
2110
2111 /* "Bind" before-change-functions and after-change-functions
2112 to nil--but in a way that errors don't know about.
2113 That way, if there's an error in them, they will stay nil. */
2114 before_change_functions = Vbefore_change_functions;
2115 after_change_functions = Vafter_change_functions;
2116 Vbefore_change_functions = Qnil;
2117 Vafter_change_functions = Qnil;
2118 GCPRO2 (before_change_functions, after_change_functions);
2119
2120 /* Actually run the hook functions. */
2121 args[0] = Qbefore_change_functions;
2122 args[1] = FETCH_START;
2123 args[2] = FETCH_END;
2124 run_hook_list_with_args (before_change_functions, 3, args);
2125
2126 /* "Unbind" the variables we "bound" to nil. */
2127 Vbefore_change_functions = before_change_functions;
2128 Vafter_change_functions = after_change_functions;
2129 UNGCPRO;
2130 }
2131
2132 if (!NILP (current_buffer->overlays_before)
2133 || !NILP (current_buffer->overlays_after))
2134 {
2135 PRESERVE_VALUE;
2136 report_overlay_modification (FETCH_START, FETCH_END, 0,
2137 FETCH_START, FETCH_END, Qnil);
2138 }
2139
2140 if (! NILP (start_marker))
2141 free_marker (start_marker);
2142 if (! NILP (end_marker))
2143 free_marker (end_marker);
2144 RESTORE_VALUE;
2145 UNGCPRO;
2146 }
2147
2148 /* Signal a change immediately after it happens.
2149 CHARPOS is the character position of the start of the changed text.
2150 LENDEL is the number of characters of the text before the change.
2151 (Not the whole buffer; just the part that was changed.)
2152 LENINS is the number of characters in that part of the text
2153 after the change. */
2154
2155 void
2156 signal_after_change (charpos, lendel, lenins)
2157 int charpos, lendel, lenins;
2158 {
2159 /* If we are deferring calls to the after-change functions
2160 and there are no before-change functions,
2161 just record the args that we were going to use. */
2162 if (! NILP (Vcombine_after_change_calls)
2163 && NILP (Vbefore_change_function) && NILP (Vbefore_change_functions)
2164 && NILP (current_buffer->overlays_before)
2165 && NILP (current_buffer->overlays_after))
2166 {
2167 Lisp_Object elt;
2168
2169 if (!NILP (combine_after_change_list)
2170 && current_buffer != XBUFFER (combine_after_change_buffer))
2171 Fcombine_after_change_execute ();
2172
2173 elt = Fcons (make_number (charpos - BEG),
2174 Fcons (make_number (Z - (charpos - lendel + lenins)),
2175 Fcons (make_number (lenins - lendel), Qnil)));
2176 combine_after_change_list
2177 = Fcons (elt, combine_after_change_list);
2178 combine_after_change_buffer = Fcurrent_buffer ();
2179
2180 return;
2181 }
2182
2183 if (!NILP (combine_after_change_list))
2184 Fcombine_after_change_execute ();
2185
2186 /* Run the after-change-function if any.
2187 We don't bother "binding" this variable to nil
2188 because it is obsolete anyway and new code should not use it. */
2189 if (!NILP (Vafter_change_function))
2190 call3 (Vafter_change_function,
2191 make_number (charpos), make_number (charpos + lenins),
2192 make_number (lendel));
2193
2194 if (!NILP (Vafter_change_functions))
2195 {
2196 Lisp_Object args[4];
2197 Lisp_Object before_change_functions;
2198 Lisp_Object after_change_functions;
2199 struct gcpro gcpro1, gcpro2;
2200
2201 /* "Bind" before-change-functions and after-change-functions
2202 to nil--but in a way that errors don't know about.
2203 That way, if there's an error in them, they will stay nil. */
2204 before_change_functions = Vbefore_change_functions;
2205 after_change_functions = Vafter_change_functions;
2206 Vbefore_change_functions = Qnil;
2207 Vafter_change_functions = Qnil;
2208 GCPRO2 (before_change_functions, after_change_functions);
2209
2210 /* Actually run the hook functions. */
2211 args[0] = Qafter_change_functions;
2212 XSETFASTINT (args[1], charpos);
2213 XSETFASTINT (args[2], charpos + lenins);
2214 XSETFASTINT (args[3], lendel);
2215 run_hook_list_with_args (after_change_functions,
2216 4, args);
2217
2218 /* "Unbind" the variables we "bound" to nil. */
2219 Vbefore_change_functions = before_change_functions;
2220 Vafter_change_functions = after_change_functions;
2221 UNGCPRO;
2222 }
2223
2224 if (!NILP (current_buffer->overlays_before)
2225 || !NILP (current_buffer->overlays_after))
2226 report_overlay_modification (make_number (charpos),
2227 make_number (charpos + lenins),
2228 1,
2229 make_number (charpos),
2230 make_number (charpos + lenins),
2231 make_number (lendel));
2232
2233 /* After an insertion, call the text properties
2234 insert-behind-hooks or insert-in-front-hooks. */
2235 if (lendel == 0)
2236 report_interval_modification (charpos, charpos + lenins);
2237 }
2238
2239 Lisp_Object
2240 Fcombine_after_change_execute_1 (val)
2241 Lisp_Object val;
2242 {
2243 Vcombine_after_change_calls = val;
2244 return val;
2245 }
2246
2247 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
2248 Scombine_after_change_execute, 0, 0, 0,
2249 "This function is for use internally in `combine-after-change-calls'.")
2250 ()
2251 {
2252 register Lisp_Object val;
2253 int count = specpdl_ptr - specpdl;
2254 int beg, end, change;
2255 int begpos, endpos;
2256 Lisp_Object tail;
2257
2258 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
2259
2260 Fset_buffer (combine_after_change_buffer);
2261
2262 /* # chars unchanged at beginning of buffer. */
2263 beg = Z - BEG;
2264 /* # chars unchanged at end of buffer. */
2265 end = beg;
2266 /* Total amount of insertion (negative for deletion). */
2267 change = 0;
2268
2269 /* Scan the various individual changes,
2270 accumulating the range info in BEG, END and CHANGE. */
2271 for (tail = combine_after_change_list; CONSP (tail);
2272 tail = XCONS (tail)->cdr)
2273 {
2274 Lisp_Object elt;
2275 int thisbeg, thisend, thischange;
2276
2277 /* Extract the info from the next element. */
2278 elt = XCONS (tail)->car;
2279 if (! CONSP (elt))
2280 continue;
2281 thisbeg = XINT (XCONS (elt)->car);
2282
2283 elt = XCONS (elt)->cdr;
2284 if (! CONSP (elt))
2285 continue;
2286 thisend = XINT (XCONS (elt)->car);
2287
2288 elt = XCONS (elt)->cdr;
2289 if (! CONSP (elt))
2290 continue;
2291 thischange = XINT (XCONS (elt)->car);
2292
2293 /* Merge this range into the accumulated range. */
2294 change += thischange;
2295 if (thisbeg < beg)
2296 beg = thisbeg;
2297 if (thisend < end)
2298 end = thisend;
2299 }
2300
2301 /* Get the current start and end positions of the range
2302 that was changed. */
2303 begpos = BEG + beg;
2304 endpos = Z - end;
2305
2306 /* We are about to handle these, so discard them. */
2307 combine_after_change_list = Qnil;
2308
2309 /* Now run the after-change functions for real.
2310 Turn off the flag that defers them. */
2311 record_unwind_protect (Fcombine_after_change_execute_1,
2312 Vcombine_after_change_calls);
2313 signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
2314
2315 return unbind_to (count, val);
2316 }
2317 \f
2318 syms_of_insdel ()
2319 {
2320 staticpro (&combine_after_change_list);
2321 combine_after_change_list = Qnil;
2322
2323 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
2324 "Used internally by the `combine-after-change-calls' macro.");
2325 Vcombine_after_change_calls = Qnil;
2326
2327 defsubr (&Scombine_after_change_execute);
2328 }