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