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