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