]> code.delx.au - gnu-emacs/blob - src/insdel.c
(insert_from_buffer_1): Adjust FROM position by number
[gnu-emacs] / 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 {
1550 if (buf == current_buffer && PT <= from)
1551 from += nchars;
1552 intervals = copy_intervals (intervals, from, nchars);
1553 }
1554
1555 /* Insert those intervals. */
1556 graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
1557
1558 {
1559 int pos = PT, pos_byte = PT_BYTE;
1560
1561 adjust_point (nchars + combined_after_bytes,
1562 outgoing_nbytes + combined_after_bytes);
1563
1564 if (combined_after_bytes)
1565 combine_bytes (pos + nchars, pos_byte + outgoing_nbytes,
1566 combined_after_bytes);
1567
1568 if (combined_before_bytes)
1569 combine_bytes (pos, pos_byte, combined_before_bytes);
1570 }
1571 }
1572 \f
1573 /* This function should be called after moving gap to FROM and before
1574 altering text between FROM and TO. This adjusts various position
1575 keepers and markers as if the text is deleted. Don't forget to
1576 call adjust_after_replace after you actually alter the text. */
1577
1578 void
1579 adjust_before_replace (from, from_byte, to, to_byte)
1580 int from, from_byte, to, to_byte;
1581 {
1582 Lisp_Object deletion;
1583
1584 if (! EQ (current_buffer->undo_list, Qt))
1585 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1586
1587 CHECK_MARKERS ();
1588
1589 adjust_markers_for_delete (from, from_byte, to, to_byte);
1590
1591 if (! EQ (current_buffer->undo_list, Qt))
1592 record_delete (from, deletion);
1593
1594 adjust_overlays_for_delete (from, to - from);
1595 }
1596
1597 /* Record undo information and adjust markers and position keepers for
1598 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1599 chars (LEN_BYTE bytes) which resides in the gap just after
1600 GPT_ADDR.
1601
1602 PREV_TEXT nil means the new text was just inserted. */
1603
1604 void
1605 adjust_after_replace (from, from_byte, prev_text, len, len_byte)
1606 int from, from_byte, len, len_byte;
1607 Lisp_Object prev_text;
1608 {
1609 int combined_before_bytes
1610 = count_combining_before (GPT_ADDR, len_byte, from, from_byte);
1611 int combined_after_bytes
1612 = count_combining_after (GPT_ADDR, len_byte, from, from_byte);
1613 /* This flag tells if we combine some bytes with a character before
1614 FROM. This happens even if combined_before_bytes is zero. */
1615 int combine_before = (combined_before_bytes
1616 || (len == 0 && combined_after_bytes));
1617
1618 int nchars_del = 0, nbytes_del = 0;
1619
1620 if (STRINGP (prev_text))
1621 {
1622 nchars_del = XSTRING (prev_text)->size;
1623 nbytes_del = STRING_BYTES (XSTRING (prev_text));
1624 }
1625
1626 if ((combine_before && from == BEGV)
1627 || (combined_after_bytes && from == ZV))
1628 {
1629 /* We can't combine bytes nor signal an error here. So, let's
1630 pretend that the new text is just a single space. */
1631 len = len_byte = 1;
1632 combined_before_bytes = combined_after_bytes = 0;
1633 *(GPT_ADDR) = ' ';
1634 }
1635
1636 if (combined_after_bytes)
1637 {
1638 Lisp_Object deletion;
1639 deletion = Qnil;
1640
1641 if (! EQ (current_buffer->undo_list, Qt))
1642 deletion = make_buffer_string_both (from, from_byte,
1643 from + combined_after_bytes,
1644 from_byte + combined_after_bytes,
1645 1);
1646
1647 adjust_markers_for_record_delete (from, from_byte,
1648 from + combined_after_bytes,
1649 from_byte + combined_after_bytes);
1650
1651 if (! EQ (current_buffer->undo_list, Qt))
1652 record_delete (from + nchars_del, deletion);
1653 }
1654
1655 if (combined_before_bytes
1656 || (len_byte == 0 && combined_after_bytes > 0))
1657 {
1658 Lisp_Object deletion;
1659 deletion = Qnil;
1660
1661 if (! EQ (current_buffer->undo_list, Qt))
1662 deletion = make_buffer_string_both (from - 1, CHAR_TO_BYTE (from - 1),
1663 from, from_byte, 1);
1664 adjust_markers_for_record_delete (from - 1, CHAR_TO_BYTE (from - 1),
1665 from, from_byte);
1666 if (! EQ (current_buffer->undo_list, Qt))
1667 record_delete (from - 1, deletion);
1668 }
1669
1670 /* Update various buffer positions for the new text. */
1671 GAP_SIZE -= len_byte;
1672 ZV += len; Z+= len;
1673 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1674 GPT += len; GPT_BYTE += len_byte;
1675 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1676
1677 /* The gap should be at character boundary. */
1678 if (combined_after_bytes)
1679 move_gap_both (GPT + combined_after_bytes,
1680 GPT_BYTE + combined_after_bytes);
1681
1682 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1683 len, len_byte,
1684 combined_before_bytes, combined_after_bytes);
1685 if (! EQ (current_buffer->undo_list, Qt))
1686 {
1687 if (nchars_del > 0)
1688 record_delete (from - combine_before, prev_text);
1689 if (combine_before)
1690 record_insert (from - 1, len - combined_before_bytes + 1);
1691 else
1692 record_insert (from, len);
1693 }
1694
1695 if (len > nchars_del)
1696 adjust_overlays_for_insert (from, len - nchars_del);
1697 else if (len < nchars_del)
1698 adjust_overlays_for_delete (from, nchars_del - len);
1699 if (BUF_INTERVALS (current_buffer) != 0)
1700 {
1701 offset_intervals (current_buffer, from, len - nchars_del);
1702 }
1703
1704 {
1705 if (from < PT)
1706 adjust_point (len - nchars_del, len_byte - nbytes_del);
1707
1708 if (combined_after_bytes)
1709 {
1710 if (combined_before_bytes == len_byte)
1711 /* This is the case that all new bytes are combined. */
1712 combined_before_bytes += combined_after_bytes;
1713 else
1714 combine_bytes (from + len, from_byte + len_byte,
1715 combined_after_bytes);
1716 }
1717 if (combined_before_bytes)
1718 combine_bytes (from, from_byte, combined_before_bytes);
1719 }
1720
1721 /* As byte combining will decrease Z, we must check this again. */
1722 if (Z - GPT < END_UNCHANGED)
1723 END_UNCHANGED = Z - GPT;
1724
1725 CHECK_MARKERS ();
1726
1727 if (len == 0)
1728 evaporate_overlays (from);
1729 MODIFF++;
1730 }
1731
1732 /* Record undo information, adjust markers and position keepers for an
1733 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1734 text already exists in the current buffer but character length (TO
1735 - FROM) may be incorrect, the correct length is NEWLEN. */
1736
1737 void
1738 adjust_after_insert (from, from_byte, to, to_byte, newlen)
1739 int from, from_byte, to, to_byte, newlen;
1740 {
1741 int len = to - from, len_byte = to_byte - from_byte;
1742
1743 if (GPT != to)
1744 move_gap_both (to, to_byte);
1745 GAP_SIZE += len_byte;
1746 GPT -= len; GPT_BYTE -= len_byte;
1747 ZV -= len; ZV_BYTE -= len_byte;
1748 Z -= len; Z_BYTE -= len_byte;
1749 adjust_after_replace (from, from_byte, Qnil, newlen, len_byte);
1750 }
1751
1752 /* Replace the text from character positions FROM to TO with NEW,
1753 If PREPARE is nonzero, call prepare_to_modify_buffer.
1754 If INHERIT, the newly inserted text should inherit text properties
1755 from the surrounding non-deleted text. */
1756
1757 /* Note that this does not yet handle markers quite right.
1758 Also it needs to record a single undo-entry that does a replacement
1759 rather than a separate delete and insert.
1760 That way, undo will also handle markers properly.
1761
1762 But if MARKERS is 0, don't relocate markers. */
1763
1764 void
1765 replace_range (from, to, new, prepare, inherit, markers)
1766 Lisp_Object new;
1767 int from, to, prepare, inherit, markers;
1768 {
1769 int inschars = XSTRING (new)->size;
1770 int insbytes = STRING_BYTES (XSTRING (new));
1771 int from_byte, to_byte;
1772 int nbytes_del, nchars_del;
1773 register Lisp_Object temp;
1774 struct gcpro gcpro1;
1775 int combined_before_bytes, combined_after_bytes;
1776 INTERVAL intervals;
1777 int outgoing_insbytes = insbytes;
1778 Lisp_Object deletion;
1779
1780 CHECK_MARKERS ();
1781
1782 GCPRO1 (new);
1783
1784 if (prepare)
1785 {
1786 int range_length = to - from;
1787 prepare_to_modify_buffer (from, to, &from);
1788 to = from + range_length;
1789 }
1790
1791 UNGCPRO;
1792
1793 /* Make args be valid */
1794 if (from < BEGV)
1795 from = BEGV;
1796 if (to > ZV)
1797 to = ZV;
1798
1799 from_byte = CHAR_TO_BYTE (from);
1800 to_byte = CHAR_TO_BYTE (to);
1801
1802 nchars_del = to - from;
1803 nbytes_del = to_byte - from_byte;
1804
1805 if (nbytes_del <= 0 && insbytes == 0)
1806 return;
1807
1808 /* Make OUTGOING_INSBYTES describe the text
1809 as it will be inserted in this buffer. */
1810
1811 if (NILP (current_buffer->enable_multibyte_characters))
1812 outgoing_insbytes = inschars;
1813 else if (! STRING_MULTIBYTE (new))
1814 outgoing_insbytes
1815 = count_size_as_multibyte (XSTRING (new)->data, insbytes);
1816
1817 /* Make sure point-max won't overflow after this insertion. */
1818 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1819 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1820 error ("Maximum buffer size exceeded");
1821
1822 GCPRO1 (new);
1823
1824 /* Make sure the gap is somewhere in or next to what we are deleting. */
1825 if (from > GPT)
1826 gap_right (from, from_byte);
1827 if (to < GPT)
1828 gap_left (to, to_byte, 0);
1829
1830 /* Even if we don't record for undo, we must keep the original text
1831 because we may have to recover it because of inappropriate byte
1832 combining. */
1833 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1834
1835 if (markers)
1836 /* Relocate all markers pointing into the new, larger gap
1837 to point at the end of the text before the gap.
1838 Do this before recording the deletion,
1839 so that undo handles this after reinserting the text. */
1840 adjust_markers_for_delete (from, from_byte, to, to_byte);
1841
1842 GAP_SIZE += nbytes_del;
1843 ZV -= nchars_del;
1844 Z -= nchars_del;
1845 ZV_BYTE -= nbytes_del;
1846 Z_BYTE -= nbytes_del;
1847 GPT = from;
1848 GPT_BYTE = from_byte;
1849 *(GPT_ADDR) = 0; /* Put an anchor. */
1850
1851 if (GPT_BYTE < GPT)
1852 abort ();
1853
1854 if (GPT - BEG < BEG_UNCHANGED)
1855 BEG_UNCHANGED = GPT - BEG;
1856 if (Z - GPT < END_UNCHANGED)
1857 END_UNCHANGED = Z - GPT;
1858
1859 if (GAP_SIZE < insbytes)
1860 make_gap (insbytes - GAP_SIZE);
1861
1862 /* Copy the string text into the buffer, perhaps converting
1863 between single-byte and multibyte. */
1864 copy_text (XSTRING (new)->data, GPT_ADDR, insbytes,
1865 STRING_MULTIBYTE (new),
1866 ! NILP (current_buffer->enable_multibyte_characters));
1867
1868 /* We have copied text into the gap, but we have not marked
1869 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1870 here, for both the previous text and the following text.
1871 Meanwhile, GPT_ADDR does point to
1872 the text that has been stored by copy_text. */
1873
1874 combined_before_bytes
1875 = count_combining_before (GPT_ADDR, outgoing_insbytes, from, from_byte);
1876 combined_after_bytes
1877 = count_combining_after (GPT_ADDR, outgoing_insbytes, from, from_byte);
1878
1879 if ((combined_before_bytes && from == BEGV)
1880 || (combined_after_bytes && from == ZV))
1881 {
1882 /* Bytes are being combined across the region boundary. We
1883 should avoid it. We recover the original contents before
1884 signaling an error. */
1885 bcopy (XSTRING (deletion)->data, GPT_ADDR, nbytes_del);
1886 GAP_SIZE -= nbytes_del;
1887 ZV += nchars_del;
1888 Z += nchars_del;
1889 ZV_BYTE += nbytes_del;
1890 Z_BYTE += nbytes_del;
1891 GPT = from + nchars_del;
1892 GPT_BYTE = from_byte + nbytes_del;
1893 *(GPT_ADDR) = 0; /* Put an anchor. */
1894 if (markers)
1895 adjust_markers_for_insert (from, from_byte, to, to_byte, 0, 0, 0);
1896 UNGCPRO;
1897 byte_combining_error ();
1898 GCPRO1 (new);
1899 }
1900
1901 /* Record deletion of the surrounding text that combines with
1902 the insertion. This, together with recording the insertion,
1903 will add up to the right stuff in the undo list.
1904
1905 But there is no need to actually delete the combining bytes
1906 from the buffer and reinsert them. */
1907
1908 if (combined_after_bytes)
1909 {
1910 Lisp_Object deletion;
1911 deletion = Qnil;
1912
1913 if (! EQ (current_buffer->undo_list, Qt))
1914 deletion = make_buffer_string_both (from, from_byte,
1915 from + combined_after_bytes,
1916 from_byte + combined_after_bytes,
1917 1);
1918
1919 adjust_markers_for_record_delete (from, from_byte,
1920 from + combined_after_bytes,
1921 from_byte + combined_after_bytes);
1922 if (! EQ (current_buffer->undo_list, Qt))
1923 record_delete (from + nchars_del, deletion);
1924 }
1925
1926 if (combined_before_bytes)
1927 {
1928 Lisp_Object deletion;
1929 deletion = Qnil;
1930
1931 if (! EQ (current_buffer->undo_list, Qt))
1932 deletion = make_buffer_string_both (from - 1, CHAR_TO_BYTE (from - 1),
1933 from, from_byte, 1);
1934 adjust_markers_for_record_delete (from - 1, CHAR_TO_BYTE (from - 1),
1935 from, from_byte);
1936 if (! EQ (current_buffer->undo_list, Qt))
1937 record_delete (from - 1, deletion);
1938 }
1939
1940 if (! EQ (current_buffer->undo_list, Qt))
1941 {
1942 record_delete (from - !!combined_before_bytes, deletion);
1943 record_insert (from - !!combined_before_bytes,
1944 (inschars - combined_before_bytes
1945 + !!combined_before_bytes));
1946 }
1947
1948 GAP_SIZE -= outgoing_insbytes;
1949 GPT += inschars;
1950 ZV += inschars;
1951 Z += inschars;
1952 GPT_BYTE += outgoing_insbytes;
1953 ZV_BYTE += outgoing_insbytes;
1954 Z_BYTE += outgoing_insbytes;
1955 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1956
1957 if (combined_after_bytes)
1958 move_gap_both (GPT + combined_after_bytes,
1959 GPT_BYTE + combined_after_bytes);
1960
1961 if (GPT_BYTE < GPT)
1962 abort ();
1963
1964 /* Adjust the overlay center as needed. This must be done after
1965 adjusting the markers that bound the overlays. */
1966 adjust_overlays_for_delete (from, nchars_del);
1967 adjust_overlays_for_insert (from, inschars);
1968 if (markers)
1969 adjust_markers_for_insert (from, from_byte,
1970 from + inschars, from_byte + outgoing_insbytes,
1971 combined_before_bytes, combined_after_bytes, 0);
1972
1973 offset_intervals (current_buffer, from, inschars - nchars_del);
1974
1975 /* Get the intervals for the part of the string we are inserting--
1976 not including the combined-before bytes. */
1977 intervals = XSTRING (new)->intervals;
1978 /* Insert those intervals. */
1979 graft_intervals_into_buffer (intervals, from, inschars,
1980 current_buffer, inherit);
1981
1982 /* Relocate point as if it were a marker. */
1983 if (from < PT)
1984 adjust_point ((from + inschars - (PT < to ? PT : to)),
1985 (from_byte + outgoing_insbytes
1986 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
1987
1988 if (combined_after_bytes)
1989 {
1990 if (combined_before_bytes == outgoing_insbytes)
1991 /* This is the case that all new bytes are combined. */
1992 combined_before_bytes += combined_after_bytes;
1993 else
1994 combine_bytes (from + inschars, from_byte + outgoing_insbytes,
1995 combined_after_bytes);
1996 }
1997 if (combined_before_bytes)
1998 combine_bytes (from, from_byte, combined_before_bytes);
1999
2000 /* As byte combining will decrease Z, we must check this again. */
2001 if (Z - GPT < END_UNCHANGED)
2002 END_UNCHANGED = Z - GPT;
2003
2004 if (outgoing_insbytes == 0)
2005 evaporate_overlays (from);
2006
2007 CHECK_MARKERS ();
2008
2009 MODIFF++;
2010 UNGCPRO;
2011
2012 signal_after_change (from, nchars_del, GPT - from);
2013 update_compositions (from, GPT, CHECK_BORDER);
2014 }
2015 \f
2016 /* Delete characters in current buffer
2017 from FROM up to (but not including) TO.
2018 If TO comes before FROM, we delete nothing. */
2019
2020 void
2021 del_range (from, to)
2022 register int from, to;
2023 {
2024 del_range_1 (from, to, 1, 0);
2025 }
2026
2027 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
2028 RET_STRING says to return the deleted text. */
2029
2030 Lisp_Object
2031 del_range_1 (from, to, prepare, ret_string)
2032 int from, to, prepare, ret_string;
2033 {
2034 int from_byte, to_byte;
2035 Lisp_Object deletion;
2036 struct gcpro gcpro1;
2037
2038 /* Make args be valid */
2039 if (from < BEGV)
2040 from = BEGV;
2041 if (to > ZV)
2042 to = ZV;
2043
2044 if (to <= from)
2045 return Qnil;
2046
2047 if (prepare)
2048 {
2049 int range_length = to - from;
2050 prepare_to_modify_buffer (from, to, &from);
2051 to = from + range_length;
2052 }
2053
2054 from_byte = CHAR_TO_BYTE (from);
2055 to_byte = CHAR_TO_BYTE (to);
2056
2057 deletion = del_range_2 (from, from_byte, to, to_byte, ret_string);
2058 GCPRO1(deletion);
2059 signal_after_change (from, to - from, 0);
2060 update_compositions (from, from, CHECK_HEAD);
2061 UNGCPRO;
2062 return deletion;
2063 }
2064
2065 /* Like del_range_1 but args are byte positions, not char positions. */
2066
2067 void
2068 del_range_byte (from_byte, to_byte, prepare)
2069 int from_byte, to_byte, prepare;
2070 {
2071 int from, to;
2072
2073 /* Make args be valid */
2074 if (from_byte < BEGV_BYTE)
2075 from_byte = BEGV_BYTE;
2076 if (to_byte > ZV_BYTE)
2077 to_byte = ZV_BYTE;
2078
2079 if (to_byte <= from_byte)
2080 return;
2081
2082 from = BYTE_TO_CHAR (from_byte);
2083 to = BYTE_TO_CHAR (to_byte);
2084
2085 if (prepare)
2086 {
2087 int old_from = from, old_to = Z - to;
2088 int range_length = to - from;
2089 prepare_to_modify_buffer (from, to, &from);
2090 to = from + range_length;
2091
2092 if (old_from != from)
2093 from_byte = CHAR_TO_BYTE (from);
2094 if (old_to == Z - to)
2095 to_byte = CHAR_TO_BYTE (to);
2096 }
2097
2098 del_range_2 (from, from_byte, to, to_byte, 0);
2099 signal_after_change (from, to - from, 0);
2100 update_compositions (from, from, CHECK_HEAD);
2101 }
2102
2103 /* Like del_range_1, but positions are specified both as charpos
2104 and bytepos. */
2105
2106 void
2107 del_range_both (from, from_byte, to, to_byte, prepare)
2108 int from, from_byte, to, to_byte, prepare;
2109 {
2110 /* Make args be valid */
2111 if (from_byte < BEGV_BYTE)
2112 from_byte = BEGV_BYTE;
2113 if (to_byte > ZV_BYTE)
2114 to_byte = ZV_BYTE;
2115
2116 if (to_byte <= from_byte)
2117 return;
2118
2119 if (from < BEGV)
2120 from = BEGV;
2121 if (to > ZV)
2122 to = ZV;
2123
2124 if (prepare)
2125 {
2126 int old_from = from, old_to = Z - to;
2127 int range_length = to - from;
2128 prepare_to_modify_buffer (from, to, &from);
2129 to = from + range_length;
2130
2131 if (old_from != from)
2132 from_byte = CHAR_TO_BYTE (from);
2133 if (old_to == Z - to)
2134 to_byte = CHAR_TO_BYTE (to);
2135 }
2136
2137 del_range_2 (from, from_byte, to, to_byte, 0);
2138 signal_after_change (from, to - from, 0);
2139 update_compositions (from, from, CHECK_HEAD);
2140 }
2141
2142 /* Delete a range of text, specified both as character positions
2143 and byte positions. FROM and TO are character positions,
2144 while FROM_BYTE and TO_BYTE are byte positions.
2145 If RET_STRING is true, the deleted area is returned as a string. */
2146
2147 Lisp_Object
2148 del_range_2 (from, from_byte, to, to_byte, ret_string)
2149 int from, from_byte, to, to_byte, ret_string;
2150 {
2151 register int nbytes_del, nchars_del;
2152 int combined_after_bytes;
2153 Lisp_Object deletion;
2154 int from_byte_1;
2155
2156 CHECK_MARKERS ();
2157
2158 nchars_del = to - from;
2159 nbytes_del = to_byte - from_byte;
2160
2161 /* Make sure the gap is somewhere in or next to what we are deleting. */
2162 if (from > GPT)
2163 gap_right (from, from_byte);
2164 if (to < GPT)
2165 gap_left (to, to_byte, 0);
2166
2167 combined_after_bytes
2168 = count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte),
2169 Z_BYTE - to_byte, from, from_byte);
2170 if (combined_after_bytes)
2171 {
2172 if (from == BEGV || to == ZV)
2173 byte_combining_error ();
2174 from_byte_1 = from_byte;
2175 DEC_POS (from_byte_1);
2176 }
2177 else
2178 from_byte_1 = from_byte;
2179
2180 if (ret_string || ! EQ (current_buffer->undo_list, Qt))
2181 deletion
2182 = make_buffer_string_both (from - !!combined_after_bytes,
2183 from_byte_1,
2184 to + combined_after_bytes,
2185 to_byte + combined_after_bytes, 1);
2186 else
2187 deletion = Qnil;
2188
2189 if (combined_after_bytes)
2190 /* COMBINED_AFTER_BYTES nonzero means that the above code moved
2191 the gap. We must move the gap again to a proper place. */
2192 move_gap_both (from, from_byte);
2193
2194 /* Relocate all markers pointing into the new, larger gap
2195 to point at the end of the text before the gap.
2196 Do this before recording the deletion,
2197 so that undo handles this after reinserting the text. */
2198 adjust_markers_for_delete (from, from_byte, to, to_byte);
2199 if (combined_after_bytes)
2200 {
2201 /* Adjust markers for the phony deletion
2202 that we are about to call record_undo for. */
2203
2204 /* Here we delete the markers that formerly
2205 pointed at TO ... TO + COMBINED_AFTER_BYTES.
2206 But because of the call to adjust_markers_for_delete, above,
2207 they now point at FROM ... FROM + COMBINED_AFTER_BYTES. */
2208 adjust_markers_for_record_delete (from, from_byte,
2209 from + combined_after_bytes,
2210 from_byte + combined_after_bytes);
2211
2212 adjust_markers_for_record_delete (from - 1, from_byte_1,
2213 from, from_byte);
2214 }
2215 if (! EQ (current_buffer->undo_list, Qt))
2216 record_delete (from - !!combined_after_bytes, deletion);
2217 MODIFF++;
2218
2219 /* Relocate point as if it were a marker. */
2220 if (from < PT)
2221 adjust_point (from - (PT < to ? PT : to),
2222 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte));
2223
2224 offset_intervals (current_buffer, from, - nchars_del);
2225
2226 /* Adjust the overlay center as needed. This must be done after
2227 adjusting the markers that bound the overlays. */
2228 adjust_overlays_for_delete (from, nchars_del);
2229
2230 GAP_SIZE += nbytes_del;
2231 ZV_BYTE -= nbytes_del;
2232 Z_BYTE -= nbytes_del;
2233 ZV -= nchars_del;
2234 Z -= nchars_del;
2235 GPT = from;
2236 GPT_BYTE = from_byte;
2237
2238 if (combined_after_bytes)
2239 move_gap_both (GPT + combined_after_bytes,
2240 GPT_BYTE + combined_after_bytes);
2241
2242 *(GPT_ADDR) = 0; /* Put an anchor. */
2243
2244 if (GPT_BYTE < GPT)
2245 abort ();
2246
2247 if (GPT - BEG < BEG_UNCHANGED)
2248 BEG_UNCHANGED = GPT - BEG;
2249 if (Z - GPT < END_UNCHANGED)
2250 END_UNCHANGED = Z - GPT;
2251
2252 if (combined_after_bytes)
2253 {
2254 /* Adjust markers for byte combining. As we have already
2255 adjuted markers without concerning byte combining, here we
2256 must concern only byte combining. */
2257 adjust_markers_for_replace (from, from_byte, 0, 0, 0, 0,
2258 0, combined_after_bytes);
2259 combine_bytes (from, from_byte, combined_after_bytes);
2260
2261 record_insert (GPT - 1, 1);
2262
2263 if (Z - GPT < END_UNCHANGED)
2264 END_UNCHANGED = Z - GPT;
2265 }
2266
2267 CHECK_MARKERS ();
2268
2269 evaporate_overlays (from);
2270
2271 return deletion;
2272 }
2273 \f
2274 /* Call this if you're about to change the region of BUFFER from
2275 character positions START to END. This checks the read-only
2276 properties of the region, calls the necessary modification hooks,
2277 and warns the next redisplay that it should pay attention to that
2278 area. */
2279
2280 void
2281 modify_region (buffer, start, end)
2282 struct buffer *buffer;
2283 int start, end;
2284 {
2285 struct buffer *old_buffer = current_buffer;
2286
2287 if (buffer != old_buffer)
2288 set_buffer_internal (buffer);
2289
2290 prepare_to_modify_buffer (start, end, NULL);
2291
2292 BUF_COMPUTE_UNCHANGED (buffer, start - 1, 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 /* Let redisplay consider other windows than selected_window
2323 if modifying another buffer. */
2324 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
2325 ++windows_or_buffers_changed;
2326
2327 if (BUF_INTERVALS (current_buffer) != 0)
2328 {
2329 if (preserve_ptr)
2330 {
2331 Lisp_Object preserve_marker;
2332 struct gcpro gcpro1;
2333 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
2334 GCPRO1 (preserve_marker);
2335 verify_interval_modification (current_buffer, start, end);
2336 *preserve_ptr = marker_position (preserve_marker);
2337 unchain_marker (preserve_marker);
2338 UNGCPRO;
2339 }
2340 else
2341 verify_interval_modification (current_buffer, start, end);
2342 }
2343
2344 #ifdef CLASH_DETECTION
2345 if (!NILP (current_buffer->file_truename)
2346 /* Make binding buffer-file-name to nil effective. */
2347 && !NILP (current_buffer->filename)
2348 && SAVE_MODIFF >= MODIFF)
2349 lock_file (current_buffer->file_truename);
2350 #else
2351 /* At least warn if this file has changed on disk since it was visited. */
2352 if (!NILP (current_buffer->filename)
2353 && SAVE_MODIFF >= MODIFF
2354 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2355 && !NILP (Ffile_exists_p (current_buffer->filename)))
2356 call1 (intern ("ask-user-about-supersession-threat"),
2357 current_buffer->filename);
2358 #endif /* not CLASH_DETECTION */
2359
2360 signal_before_change (start, end, preserve_ptr);
2361
2362 if (current_buffer->newline_cache)
2363 invalidate_region_cache (current_buffer,
2364 current_buffer->newline_cache,
2365 start - BEG, Z - end);
2366 if (current_buffer->width_run_cache)
2367 invalidate_region_cache (current_buffer,
2368 current_buffer->width_run_cache,
2369 start - BEG, Z - end);
2370
2371 Vdeactivate_mark = Qt;
2372 }
2373 \f
2374 /* These macros work with an argument named `preserve_ptr'
2375 and a local variable named `preserve_marker'. */
2376
2377 #define PRESERVE_VALUE \
2378 if (preserve_ptr && NILP (preserve_marker)) \
2379 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2380
2381 #define RESTORE_VALUE \
2382 if (! NILP (preserve_marker)) \
2383 { \
2384 *preserve_ptr = marker_position (preserve_marker); \
2385 unchain_marker (preserve_marker); \
2386 }
2387
2388 #define PRESERVE_START_END \
2389 if (NILP (start_marker)) \
2390 start_marker = Fcopy_marker (start, Qnil); \
2391 if (NILP (end_marker)) \
2392 end_marker = Fcopy_marker (end, Qnil);
2393
2394 #define FETCH_START \
2395 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2396
2397 #define FETCH_END \
2398 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2399
2400 /* Signal a change to the buffer immediately before it happens.
2401 START_INT and END_INT are the bounds of the text to be changed.
2402
2403 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2404 by holding its value temporarily in a marker. */
2405
2406 void
2407 signal_before_change (start_int, end_int, preserve_ptr)
2408 int start_int, end_int;
2409 int *preserve_ptr;
2410 {
2411 Lisp_Object start, end;
2412 Lisp_Object start_marker, end_marker;
2413 Lisp_Object preserve_marker;
2414 struct gcpro gcpro1, gcpro2, gcpro3;
2415
2416 if (inhibit_modification_hooks)
2417 return;
2418
2419 start = make_number (start_int);
2420 end = make_number (end_int);
2421 preserve_marker = Qnil;
2422 start_marker = Qnil;
2423 end_marker = Qnil;
2424 GCPRO3 (preserve_marker, start_marker, end_marker);
2425
2426 /* If buffer is unmodified, run a special hook for that case. */
2427 if (SAVE_MODIFF >= MODIFF
2428 && !NILP (Vfirst_change_hook)
2429 && !NILP (Vrun_hooks))
2430 {
2431 PRESERVE_VALUE;
2432 PRESERVE_START_END;
2433 call1 (Vrun_hooks, Qfirst_change_hook);
2434 }
2435
2436 /* Run the before-change-function if any.
2437 We don't bother "binding" this variable to nil
2438 because it is obsolete anyway and new code should not use it. */
2439 if (!NILP (Vbefore_change_function))
2440 {
2441 PRESERVE_VALUE;
2442 PRESERVE_START_END;
2443 call2 (Vbefore_change_function, FETCH_START, FETCH_END);
2444 }
2445
2446 /* Now run the before-change-functions if any. */
2447 if (!NILP (Vbefore_change_functions))
2448 {
2449 Lisp_Object args[3];
2450 Lisp_Object before_change_functions;
2451 Lisp_Object after_change_functions;
2452 struct gcpro gcpro1, gcpro2;
2453
2454 PRESERVE_VALUE;
2455 PRESERVE_START_END;
2456
2457 /* "Bind" before-change-functions and after-change-functions
2458 to nil--but in a way that errors don't know about.
2459 That way, if there's an error in them, they will stay nil. */
2460 before_change_functions = Vbefore_change_functions;
2461 after_change_functions = Vafter_change_functions;
2462 Vbefore_change_functions = Qnil;
2463 Vafter_change_functions = Qnil;
2464 GCPRO2 (before_change_functions, after_change_functions);
2465
2466 /* Actually run the hook functions. */
2467 args[0] = Qbefore_change_functions;
2468 args[1] = FETCH_START;
2469 args[2] = FETCH_END;
2470 run_hook_list_with_args (before_change_functions, 3, args);
2471
2472 /* "Unbind" the variables we "bound" to nil. */
2473 Vbefore_change_functions = before_change_functions;
2474 Vafter_change_functions = after_change_functions;
2475 UNGCPRO;
2476 }
2477
2478 if (!NILP (current_buffer->overlays_before)
2479 || !NILP (current_buffer->overlays_after))
2480 {
2481 PRESERVE_VALUE;
2482 report_overlay_modification (FETCH_START, FETCH_END, 0,
2483 FETCH_START, FETCH_END, Qnil);
2484 }
2485
2486 if (! NILP (start_marker))
2487 free_marker (start_marker);
2488 if (! NILP (end_marker))
2489 free_marker (end_marker);
2490 RESTORE_VALUE;
2491 UNGCPRO;
2492 }
2493
2494 /* Signal a change immediately after it happens.
2495 CHARPOS is the character position of the start of the changed text.
2496 LENDEL is the number of characters of the text before the change.
2497 (Not the whole buffer; just the part that was changed.)
2498 LENINS is the number of characters in that part of the text
2499 after the change. */
2500
2501 void
2502 signal_after_change (charpos, lendel, lenins)
2503 int charpos, lendel, lenins;
2504 {
2505 if (inhibit_modification_hooks)
2506 return;
2507
2508 /* If we are deferring calls to the after-change functions
2509 and there are no before-change functions,
2510 just record the args that we were going to use. */
2511 if (! NILP (Vcombine_after_change_calls)
2512 && NILP (Vbefore_change_function) && NILP (Vbefore_change_functions)
2513 && NILP (current_buffer->overlays_before)
2514 && NILP (current_buffer->overlays_after))
2515 {
2516 Lisp_Object elt;
2517
2518 if (!NILP (combine_after_change_list)
2519 && current_buffer != XBUFFER (combine_after_change_buffer))
2520 Fcombine_after_change_execute ();
2521
2522 elt = Fcons (make_number (charpos - BEG),
2523 Fcons (make_number (Z - (charpos - lendel + lenins)),
2524 Fcons (make_number (lenins - lendel), Qnil)));
2525 combine_after_change_list
2526 = Fcons (elt, combine_after_change_list);
2527 combine_after_change_buffer = Fcurrent_buffer ();
2528
2529 return;
2530 }
2531
2532 if (!NILP (combine_after_change_list))
2533 Fcombine_after_change_execute ();
2534
2535 /* Run the after-change-function if any.
2536 We don't bother "binding" this variable to nil
2537 because it is obsolete anyway and new code should not use it. */
2538 if (!NILP (Vafter_change_function))
2539 call3 (Vafter_change_function,
2540 make_number (charpos), make_number (charpos + lenins),
2541 make_number (lendel));
2542
2543 if (!NILP (Vafter_change_functions))
2544 {
2545 Lisp_Object args[4];
2546 Lisp_Object before_change_functions;
2547 Lisp_Object after_change_functions;
2548 struct gcpro gcpro1, gcpro2;
2549
2550 /* "Bind" before-change-functions and after-change-functions
2551 to nil--but in a way that errors don't know about.
2552 That way, if there's an error in them, they will stay nil. */
2553 before_change_functions = Vbefore_change_functions;
2554 after_change_functions = Vafter_change_functions;
2555 Vbefore_change_functions = Qnil;
2556 Vafter_change_functions = Qnil;
2557 GCPRO2 (before_change_functions, after_change_functions);
2558
2559 /* Actually run the hook functions. */
2560 args[0] = Qafter_change_functions;
2561 XSETFASTINT (args[1], charpos);
2562 XSETFASTINT (args[2], charpos + lenins);
2563 XSETFASTINT (args[3], lendel);
2564 run_hook_list_with_args (after_change_functions,
2565 4, args);
2566
2567 /* "Unbind" the variables we "bound" to nil. */
2568 Vbefore_change_functions = before_change_functions;
2569 Vafter_change_functions = after_change_functions;
2570 UNGCPRO;
2571 }
2572
2573 if (!NILP (current_buffer->overlays_before)
2574 || !NILP (current_buffer->overlays_after))
2575 report_overlay_modification (make_number (charpos),
2576 make_number (charpos + lenins),
2577 1,
2578 make_number (charpos),
2579 make_number (charpos + lenins),
2580 make_number (lendel));
2581
2582 /* After an insertion, call the text properties
2583 insert-behind-hooks or insert-in-front-hooks. */
2584 if (lendel == 0)
2585 report_interval_modification (make_number (charpos),
2586 make_number (charpos + lenins));
2587 }
2588
2589 Lisp_Object
2590 Fcombine_after_change_execute_1 (val)
2591 Lisp_Object val;
2592 {
2593 Vcombine_after_change_calls = val;
2594 return val;
2595 }
2596
2597 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
2598 Scombine_after_change_execute, 0, 0, 0,
2599 "This function is for use internally in `combine-after-change-calls'.")
2600 ()
2601 {
2602 int count = specpdl_ptr - specpdl;
2603 int beg, end, change;
2604 int begpos, endpos;
2605 Lisp_Object tail;
2606
2607 if (NILP (combine_after_change_list))
2608 return Qnil;
2609
2610 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
2611
2612 Fset_buffer (combine_after_change_buffer);
2613
2614 /* # chars unchanged at beginning of buffer. */
2615 beg = Z - BEG;
2616 /* # chars unchanged at end of buffer. */
2617 end = beg;
2618 /* Total amount of insertion (negative for deletion). */
2619 change = 0;
2620
2621 /* Scan the various individual changes,
2622 accumulating the range info in BEG, END and CHANGE. */
2623 for (tail = combine_after_change_list; CONSP (tail);
2624 tail = XCDR (tail))
2625 {
2626 Lisp_Object elt;
2627 int thisbeg, thisend, thischange;
2628
2629 /* Extract the info from the next element. */
2630 elt = XCAR (tail);
2631 if (! CONSP (elt))
2632 continue;
2633 thisbeg = XINT (XCAR (elt));
2634
2635 elt = XCDR (elt);
2636 if (! CONSP (elt))
2637 continue;
2638 thisend = XINT (XCAR (elt));
2639
2640 elt = XCDR (elt);
2641 if (! CONSP (elt))
2642 continue;
2643 thischange = XINT (XCAR (elt));
2644
2645 /* Merge this range into the accumulated range. */
2646 change += thischange;
2647 if (thisbeg < beg)
2648 beg = thisbeg;
2649 if (thisend < end)
2650 end = thisend;
2651 }
2652
2653 /* Get the current start and end positions of the range
2654 that was changed. */
2655 begpos = BEG + beg;
2656 endpos = Z - end;
2657
2658 /* We are about to handle these, so discard them. */
2659 combine_after_change_list = Qnil;
2660
2661 /* Now run the after-change functions for real.
2662 Turn off the flag that defers them. */
2663 record_unwind_protect (Fcombine_after_change_execute_1,
2664 Vcombine_after_change_calls);
2665 signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
2666 update_compositions (begpos, endpos, CHECK_ALL);
2667
2668 return unbind_to (count, Qnil);
2669 }
2670 \f
2671 void
2672 syms_of_insdel ()
2673 {
2674 staticpro (&combine_after_change_list);
2675 combine_after_change_list = Qnil;
2676 combine_after_change_buffer = Qnil;
2677
2678 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag,
2679 "Non-nil means enable debugging checks for invalid marker positions.");
2680 check_markers_debug_flag = 0;
2681 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
2682 "Used internally by the `combine-after-change-calls' macro.");
2683 Vcombine_after_change_calls = Qnil;
2684
2685 DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks,
2686 "Non-nil means don't run any of the hooks that respond to buffer changes.\n\
2687 This affects `before-change-functions' and `after-change-functions',\n\
2688 as well as hooks attached to text properties and overlays.");
2689 inhibit_modification_hooks = 0;
2690
2691 defsubr (&Scombine_after_change_execute);
2692 }