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