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