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