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