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