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