(adjust_before_replace): Comment added.
[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, 1998 Free Software Foundation, Inc.
3
4 This file is part of GNU Emacs.
5
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21
22 #include <config.h>
23 #include "lisp.h"
24 #include "intervals.h"
25 #include "buffer.h"
26 #include "charset.h"
27 #include "window.h"
28 #include "blockinput.h"
29
30 #ifndef NULL
31 #define NULL 0
32 #endif
33
34 #define min(x, y) ((x) < (y) ? (x) : (y))
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 static void adjust_markers_for_delete P_ ((int, int, int, int));
43 static void adjust_point P_ ((int, int));
44
45 Lisp_Object Fcombine_after_change_execute ();
46
47 /* Non-nil means don't call the after-change-functions right away,
48 just record an element in Vcombine_after_change_calls_list. */
49 Lisp_Object Vcombine_after_change_calls;
50
51 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
52 describing changes which happened while combine_after_change_calls
53 was nonzero. We use this to decide how to call them
54 once the deferral ends.
55
56 In each element.
57 BEG-UNCHANGED is the number of chars before the changed range.
58 END-UNCHANGED is the number of chars after the changed range,
59 and CHANGE-AMOUNT is the number of characters inserted by the change
60 (negative for a deletion). */
61 Lisp_Object combine_after_change_list;
62
63 /* Buffer which combine_after_change_list is about. */
64 Lisp_Object combine_after_change_buffer;
65
66 #define DEFAULT_NONASCII_INSERT_OFFSET 0x800
67 \f
68 /* Move gap to position CHARPOS.
69 Note that this can quit! */
70
71 void
72 move_gap (charpos)
73 int charpos;
74 {
75 move_gap_both (charpos, charpos_to_bytepos (charpos));
76 }
77
78 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
79 Note that this can quit! */
80
81 void
82 move_gap_both (charpos, bytepos)
83 int charpos, bytepos;
84 {
85 if (bytepos < GPT_BYTE)
86 gap_left (charpos, bytepos, 0);
87 else if (bytepos > GPT_BYTE)
88 gap_right (charpos, bytepos);
89 }
90
91 /* Move the gap to a position less than the current GPT.
92 BYTEPOS describes the new position as a byte position,
93 and CHARPOS is the corresponding char position.
94 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
95
96 static void
97 gap_left (charpos, bytepos, newgap)
98 register int charpos, bytepos;
99 int newgap;
100 {
101 register unsigned char *to, *from;
102 register int i;
103 int new_s1;
104
105 if (!newgap)
106 {
107 if (unchanged_modified == MODIFF
108 && overlay_unchanged_modified == OVERLAY_MODIFF)
109 {
110 beg_unchanged = charpos - BEG;
111 end_unchanged = Z - charpos;
112 }
113 else
114 {
115 if (Z - GPT < end_unchanged)
116 end_unchanged = Z - GPT;
117 if (charpos < beg_unchanged)
118 beg_unchanged = charpos - BEG;
119 }
120 }
121
122 i = GPT_BYTE;
123 to = GAP_END_ADDR;
124 from = GPT_ADDR;
125 new_s1 = GPT_BYTE;
126
127 /* Now copy the characters. To move the gap down,
128 copy characters up. */
129
130 while (1)
131 {
132 /* I gets number of characters left to copy. */
133 i = new_s1 - bytepos;
134 if (i == 0)
135 break;
136 /* If a quit is requested, stop copying now.
137 Change BYTEPOS to be where we have actually moved the gap to. */
138 if (QUITP)
139 {
140 bytepos = new_s1;
141 charpos = BYTE_TO_CHAR (bytepos);
142 break;
143 }
144 /* Move at most 32000 chars before checking again for a quit. */
145 if (i > 32000)
146 i = 32000;
147 #ifdef GAP_USE_BCOPY
148 if (i >= 128
149 /* bcopy is safe if the two areas of memory do not overlap
150 or on systems where bcopy is always safe for moving upward. */
151 && (BCOPY_UPWARD_SAFE
152 || to - from >= 128))
153 {
154 /* If overlap is not safe, avoid it by not moving too many
155 characters at once. */
156 if (!BCOPY_UPWARD_SAFE && i > to - from)
157 i = to - from;
158 new_s1 -= i;
159 from -= i, to -= i;
160 bcopy (from, to, i);
161 }
162 else
163 #endif
164 {
165 new_s1 -= i;
166 while (--i >= 0)
167 *--to = *--from;
168 }
169 }
170
171 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
172 BYTEPOS is where the loop above stopped, which may be what was specified
173 or may be where a quit was detected. */
174 adjust_markers_gap_motion (bytepos, GPT_BYTE, GAP_SIZE);
175 GPT_BYTE = bytepos;
176 GPT = charpos;
177 if (bytepos < charpos)
178 abort ();
179 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
180 QUIT;
181 }
182
183 /* Move the gap to a position greater than than the current GPT.
184 BYTEPOS describes the new position as a byte position,
185 and CHARPOS is the corresponding char position. */
186
187 static void
188 gap_right (charpos, bytepos)
189 register int charpos, bytepos;
190 {
191 register unsigned char *to, *from;
192 register int i;
193 int new_s1;
194
195 if (unchanged_modified == MODIFF
196 && overlay_unchanged_modified == OVERLAY_MODIFF)
197 {
198 beg_unchanged = charpos - BEG;
199 end_unchanged = Z - charpos;
200 }
201 else
202 {
203 if (Z - charpos - 1 < end_unchanged)
204 end_unchanged = Z - charpos;
205 if (GPT - BEG < beg_unchanged)
206 beg_unchanged = GPT - BEG;
207 }
208
209 i = GPT_BYTE;
210 from = GAP_END_ADDR;
211 to = GPT_ADDR;
212 new_s1 = GPT_BYTE;
213
214 /* Now copy the characters. To move the gap up,
215 copy characters down. */
216
217 while (1)
218 {
219 /* I gets number of characters left to copy. */
220 i = bytepos - new_s1;
221 if (i == 0)
222 break;
223 /* If a quit is requested, stop copying now.
224 Change BYTEPOS to be where we have actually moved the gap to. */
225 if (QUITP)
226 {
227 bytepos = new_s1;
228 charpos = BYTE_TO_CHAR (bytepos);
229 break;
230 }
231 /* Move at most 32000 chars before checking again for a quit. */
232 if (i > 32000)
233 i = 32000;
234 #ifdef GAP_USE_BCOPY
235 if (i >= 128
236 /* bcopy is safe if the two areas of memory do not overlap
237 or on systems where bcopy is always safe for moving downward. */
238 && (BCOPY_DOWNWARD_SAFE
239 || from - to >= 128))
240 {
241 /* If overlap is not safe, avoid it by not moving too many
242 characters at once. */
243 if (!BCOPY_DOWNWARD_SAFE && i > from - to)
244 i = from - to;
245 new_s1 += i;
246 bcopy (from, to, i);
247 from += i, to += i;
248 }
249 else
250 #endif
251 {
252 new_s1 += i;
253 while (--i >= 0)
254 *to++ = *from++;
255 }
256 }
257
258 adjust_markers_gap_motion (GPT_BYTE + GAP_SIZE, bytepos + GAP_SIZE,
259 - GAP_SIZE);
260 GPT = charpos;
261 GPT_BYTE = bytepos;
262 if (bytepos < charpos)
263 abort ();
264 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
265 QUIT;
266 }
267 \f
268 /* Add AMOUNT to the byte position of every marker in the current buffer
269 whose current byte position is between FROM (exclusive) and TO (inclusive).
270
271 Also, any markers past the outside of that interval, in the direction
272 of adjustment, are first moved back to the near end of the interval
273 and then adjusted by AMOUNT.
274
275 When the latter adjustment is done, if AMOUNT is negative,
276 we record the adjustment for undo. (This case happens only for
277 deletion.)
278
279 The markers' character positions are not altered,
280 because gap motion does not affect character positions. */
281
282 int adjust_markers_test;
283
284 static void
285 adjust_markers_gap_motion (from, to, amount)
286 register int from, to, amount;
287 {
288 /* Now that a marker has a bytepos, not counting the gap,
289 nothing needs to be done here. */
290 #if 0
291 Lisp_Object marker;
292 register struct Lisp_Marker *m;
293 register int mpos;
294
295 marker = BUF_MARKERS (current_buffer);
296
297 while (!NILP (marker))
298 {
299 m = XMARKER (marker);
300 mpos = m->bytepos;
301 if (amount > 0)
302 {
303 if (mpos > to && mpos < to + amount)
304 {
305 if (adjust_markers_test)
306 abort ();
307 mpos = to + amount;
308 }
309 }
310 else
311 {
312 /* Here's the case where a marker is inside text being deleted.
313 AMOUNT can be negative for gap motion, too,
314 but then this range contains no markers. */
315 if (mpos > from + amount && mpos <= from)
316 {
317 if (adjust_markers_test)
318 abort ();
319 mpos = from + amount;
320 }
321 }
322 if (mpos > from && mpos <= to)
323 mpos += amount;
324 m->bufpos = mpos;
325 marker = m->chain;
326 }
327 #endif
328 }
329 \f
330 /* Adjust all markers for a deletion
331 whose range in bytes is FROM_BYTE to TO_BYTE.
332 The range in charpos is FROM to TO.
333
334 This function assumes that the gap is adjacent to
335 or inside of the range being deleted. */
336
337 static void
338 adjust_markers_for_delete (from, from_byte, to, to_byte)
339 register int from, from_byte, to, to_byte;
340 {
341 Lisp_Object marker;
342 register struct Lisp_Marker *m;
343 register int charpos;
344 /* This is what GAP_SIZE will be when this deletion is finished. */
345 int coming_gap_size = GAP_SIZE + to_byte - from_byte;
346
347 marker = BUF_MARKERS (current_buffer);
348
349 while (!NILP (marker))
350 {
351 m = XMARKER (marker);
352 charpos = m->charpos;
353
354 if (charpos > Z)
355 abort ();
356
357 /* If the marker is after the deletion,
358 relocate by number of chars / bytes deleted. */
359 if (charpos > to)
360 {
361 m->charpos -= to - from;
362 m->bytepos -= to_byte - from_byte;
363 }
364
365 /* Here's the case where a marker is inside text being deleted. */
366 else if (charpos > from)
367 {
368 record_marker_adjustment (marker, from - charpos);
369 m->charpos = from;
370 m->bytepos = from_byte;
371 }
372
373 /* In a single-byte buffer, a marker's two positions must be equal. */
374 if (Z == Z_BYTE)
375 {
376 register int i = m->bytepos;
377
378 #if 0
379 /* We use FROM_BYTE here instead of GPT_BYTE
380 because FROM_BYTE is where the gap will be after the deletion. */
381 if (i > from_byte + coming_gap_size)
382 i -= coming_gap_size;
383 else if (i > from_byte)
384 i = from_byte;
385 #endif
386
387 if (m->charpos != i)
388 abort ();
389 }
390
391 marker = m->chain;
392 }
393 }
394 \f
395 /* Adjust markers for an insertion at CHARPOS / BYTEPOS
396 consisting of NCHARS chars, which are NBYTES bytes.
397
398 We have to relocate the charpos of every marker that points
399 after the insertion (but not their bytepos).
400
401 When a marker points at the insertion point,
402 we advance it if either its insertion-type is t
403 or BEFORE_MARKERS is true. */
404
405 static void
406 adjust_markers_for_insert (from, from_byte, to, to_byte, before_markers)
407 register int from, from_byte, to, to_byte, before_markers;
408 {
409 Lisp_Object marker;
410 int adjusted = 0;
411 int nchars = to - from;
412 int nbytes = to_byte - from_byte;
413
414 marker = BUF_MARKERS (current_buffer);
415
416 while (!NILP (marker))
417 {
418 register struct Lisp_Marker *m = XMARKER (marker);
419 if (m->bytepos == from_byte
420 && (m->insertion_type || before_markers))
421 {
422 m->bytepos += nbytes;
423 m->charpos += nchars;
424 if (m->insertion_type)
425 adjusted = 1;
426 }
427 else if (m->bytepos > from_byte)
428 {
429 m->bytepos += nbytes;
430 m->charpos += nchars;
431 }
432
433 /* In a single-byte buffer, a marker's two positions must be equal. */
434 if (Z == Z_BYTE)
435 {
436 register int i = m->bytepos;
437
438 #if 0
439 if (i > GPT_BYTE + GAP_SIZE)
440 i -= GAP_SIZE;
441 else if (i > GPT_BYTE)
442 i = GPT_BYTE;
443 #endif
444
445 if (m->charpos != i)
446 abort ();
447 }
448
449 marker = m->chain;
450 }
451
452 /* Adjusting only markers whose insertion-type is t may result in
453 disordered overlays in the slot `overlays_before'. */
454 if (adjusted)
455 fix_overlays_before (current_buffer, from, to);
456 }
457
458 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
459
460 This is used only when the value of point changes due to an insert
461 or delete; it does not represent a conceptual change in point as a
462 marker. In particular, point is not crossing any interval
463 boundaries, so there's no need to use the usual SET_PT macro. In
464 fact it would be incorrect to do so, because either the old or the
465 new value of point is out of sync with the current set of
466 intervals. */
467
468 static void
469 adjust_point (nchars, nbytes)
470 int nchars, nbytes;
471 {
472 BUF_PT (current_buffer) += nchars;
473 BUF_PT_BYTE (current_buffer) += nbytes;
474
475 /* In a single-byte buffer, the two positions must be equal. */
476 if (ZV == ZV_BYTE
477 && PT != PT_BYTE)
478 abort ();
479 }
480 \f
481 /* Make the gap NBYTES_ADDED bytes longer. */
482
483 void
484 make_gap (nbytes_added)
485 int nbytes_added;
486 {
487 unsigned char *result;
488 Lisp_Object tem;
489 int real_gap_loc;
490 int real_gap_loc_byte;
491 int old_gap_size;
492
493 /* If we have to get more space, get enough to last a while. */
494 nbytes_added += 2000;
495
496 /* Don't allow a buffer size that won't fit in an int
497 even if it will fit in a Lisp integer.
498 That won't work because so many places use `int'. */
499
500 if (Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added
501 >= ((unsigned) 1 << (min (BITS_PER_INT, VALBITS) - 1)))
502 error ("Buffer exceeds maximum size");
503
504 BLOCK_INPUT;
505 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */
506 result = BUFFER_REALLOC (BEG_ADDR, (Z_BYTE - BEG_BYTE
507 + GAP_SIZE + nbytes_added + 1));
508
509 if (result == 0)
510 {
511 UNBLOCK_INPUT;
512 memory_full ();
513 }
514
515 /* We can't unblock until the new address is properly stored. */
516 BEG_ADDR = result;
517 UNBLOCK_INPUT;
518
519 /* Prevent quitting in move_gap. */
520 tem = Vinhibit_quit;
521 Vinhibit_quit = Qt;
522
523 real_gap_loc = GPT;
524 real_gap_loc_byte = GPT_BYTE;
525 old_gap_size = GAP_SIZE;
526
527 /* Call the newly allocated space a gap at the end of the whole space. */
528 GPT = Z + GAP_SIZE;
529 GPT_BYTE = Z_BYTE + GAP_SIZE;
530 GAP_SIZE = nbytes_added;
531
532 /* Move the new gap down to be consecutive with the end of the old one.
533 This adjusts the markers properly too. */
534 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
535
536 /* Now combine the two into one large gap. */
537 GAP_SIZE += old_gap_size;
538 GPT = real_gap_loc;
539 GPT_BYTE = real_gap_loc_byte;
540
541 /* Put an anchor. */
542 *(Z_ADDR) = 0;
543
544 Vinhibit_quit = tem;
545 }
546 \f
547 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
548 FROM_MULTIBYTE says whether the incoming text is multibyte.
549 TO_MULTIBYTE says whether to store the text as multibyte.
550 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
551
552 Return the number of bytes stored at TO_ADDR. */
553
554 int
555 copy_text (from_addr, to_addr, nbytes,
556 from_multibyte, to_multibyte)
557 unsigned char *from_addr;
558 unsigned char *to_addr;
559 int nbytes;
560 int from_multibyte, to_multibyte;
561 {
562 if (from_multibyte == to_multibyte)
563 {
564 bcopy (from_addr, to_addr, nbytes);
565 return nbytes;
566 }
567 else if (from_multibyte)
568 {
569 int nchars = 0;
570 int bytes_left = nbytes;
571
572 /* Convert multibyte to single byte. */
573 while (bytes_left > 0)
574 {
575 int thislen, c;
576 c = STRING_CHAR_AND_LENGTH (from_addr, bytes_left, thislen);
577 *to_addr++ = SINGLE_BYTE_CHAR_P (c) ? c : (c & 0177) + 0200;
578 from_addr += thislen;
579 bytes_left--;
580 nchars++;
581 }
582 return nchars;
583 }
584 else
585 {
586 unsigned char *initial_to_addr = to_addr;
587
588 /* Convert single-byte to multibyte. */
589 while (nbytes > 0)
590 {
591 int c = *from_addr++;
592 unsigned char workbuf[4], *str;
593 int len;
594
595 if (c >= 0200 && c < 0400)
596 {
597 if (! NILP (Vnonascii_translate_table))
598 c = XINT (Faref (Vnonascii_translate_table, make_number (c)));
599 else if (nonascii_insert_offset > 0)
600 c += nonascii_insert_offset;
601 else
602 c += DEFAULT_NONASCII_INSERT_OFFSET;
603
604 len = CHAR_STRING (c, workbuf, str);
605 bcopy (str, to_addr, len);
606 to_addr += len;
607 nbytes--;
608 }
609 else
610 /* Special case for speed. */
611 *to_addr++ = c, nbytes--;
612 }
613 return to_addr - initial_to_addr;
614 }
615 }
616
617 /* Return the number of bytes it would take
618 to convert some single-byte text to multibyte.
619 The single-byte text consists of NBYTES bytes at PTR. */
620
621 int
622 count_size_as_multibyte (ptr, nbytes)
623 unsigned char *ptr;
624 int nbytes;
625 {
626 int i;
627 int outgoing_nbytes = 0;
628
629 for (i = 0; i < nbytes; i++)
630 {
631 unsigned int c = *ptr++;
632 if (c >= 0200 && c < 0400)
633 {
634 if (! NILP (Vnonascii_translate_table))
635 c = XINT (Faref (Vnonascii_translate_table, make_number (c)));
636 else if (nonascii_insert_offset > 0)
637 c += nonascii_insert_offset;
638 else
639 c += DEFAULT_NONASCII_INSERT_OFFSET;
640 }
641 outgoing_nbytes += XINT (Fchar_bytes (make_number (c)));
642 }
643
644 return outgoing_nbytes;
645 }
646 \f
647 /* Insert a string of specified length before point.
648 This function judges multibyteness based on
649 enable_multibyte_characters in the current buffer;
650 it never converts between single-byte and multibyte.
651
652 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
653 prepare_to_modify_buffer could relocate the text. */
654
655 void
656 insert (string, nbytes)
657 register unsigned char *string;
658 register nbytes;
659 {
660 if (nbytes > 0)
661 {
662 int opoint = PT;
663 insert_1 (string, nbytes, 0, 1, 0);
664 signal_after_change (opoint, 0, PT - opoint);
665 }
666 }
667
668 /* Likewise, but inherit text properties from neighboring characters. */
669
670 void
671 insert_and_inherit (string, nbytes)
672 register unsigned char *string;
673 register nbytes;
674 {
675 if (nbytes > 0)
676 {
677 int opoint = PT;
678 insert_1 (string, nbytes, 1, 1, 0);
679 signal_after_change (opoint, 0, PT - opoint);
680 }
681 }
682
683 /* Insert the character C before point. Do not inherit text properties. */
684
685 void
686 insert_char (c)
687 int c;
688 {
689 unsigned char workbuf[4], *str;
690 int len;
691
692 if (! NILP (current_buffer->enable_multibyte_characters))
693 len = CHAR_STRING (c, workbuf, str);
694 else
695 {
696 len = 1;
697 workbuf[0] = c;
698 str = workbuf;
699 }
700
701 insert (str, len);
702 }
703
704 /* Insert the null-terminated string S before point. */
705
706 void
707 insert_string (s)
708 char *s;
709 {
710 insert (s, strlen (s));
711 }
712
713 /* Like `insert' except that all markers pointing at the place where
714 the insertion happens are adjusted to point after it.
715 Don't use this function to insert part of a Lisp string,
716 since gc could happen and relocate it. */
717
718 void
719 insert_before_markers (string, nbytes)
720 unsigned char *string;
721 register int nbytes;
722 {
723 if (nbytes > 0)
724 {
725 int opoint = PT;
726
727 insert_1 (string, nbytes, 0, 1, 1);
728 signal_after_change (opoint, 0, PT - opoint);
729 }
730 }
731
732 /* Likewise, but inherit text properties from neighboring characters. */
733
734 void
735 insert_before_markers_and_inherit (string, nbytes)
736 unsigned char *string;
737 register int nbytes;
738 {
739 if (nbytes > 0)
740 {
741 int opoint = PT;
742
743 insert_1 (string, nbytes, 1, 1, 1);
744 signal_after_change (opoint, 0, PT - opoint);
745 }
746 }
747 \f
748 /* Subroutine used by the insert functions above. */
749
750 void
751 insert_1 (string, nbytes, inherit, prepare, before_markers)
752 register unsigned char *string;
753 register int nbytes;
754 int inherit, prepare, before_markers;
755 {
756 register Lisp_Object temp;
757 int nchars = chars_in_text (string, nbytes);
758
759 if (prepare)
760 prepare_to_modify_buffer (PT, PT, NULL);
761
762 if (PT != GPT)
763 move_gap_both (PT, PT_BYTE);
764 if (GAP_SIZE < nbytes)
765 make_gap (nbytes - GAP_SIZE);
766
767 record_insert (PT, nchars);
768 MODIFF++;
769
770 bcopy (string, GPT_ADDR, nbytes);
771
772 #ifdef USE_TEXT_PROPERTIES
773 if (BUF_INTERVALS (current_buffer) != 0)
774 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
775 offset_intervals (current_buffer, PT, nchars);
776 #endif
777
778 GAP_SIZE -= nbytes;
779 GPT += nchars;
780 ZV += nchars;
781 Z += nchars;
782 GPT_BYTE += nbytes;
783 ZV_BYTE += nbytes;
784 Z_BYTE += nbytes;
785 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
786 adjust_overlays_for_insert (PT, nchars);
787 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes,
788 before_markers);
789 adjust_point (nchars, nbytes);
790
791 if (GPT_BYTE < GPT)
792 abort ();
793
794 #ifdef USE_TEXT_PROPERTIES
795 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
796 Fset_text_properties (make_number (PT - nchars), make_number (PT),
797 Qnil, Qnil);
798 #endif
799 }
800
801 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
802 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
803 are the same as in insert_1. */
804
805 void
806 insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers)
807 register unsigned char *string;
808 register int nchars, nbytes;
809 int inherit, prepare, before_markers;
810 {
811 register Lisp_Object temp;
812
813 if (prepare)
814 prepare_to_modify_buffer (PT, PT, NULL);
815
816 if (PT != GPT)
817 move_gap_both (PT, PT_BYTE);
818 if (GAP_SIZE < nbytes)
819 make_gap (nbytes - GAP_SIZE);
820
821 record_insert (PT, nchars);
822 MODIFF++;
823
824 bcopy (string, GPT_ADDR, nbytes);
825
826 #ifdef USE_TEXT_PROPERTIES
827 if (BUF_INTERVALS (current_buffer) != 0)
828 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
829 offset_intervals (current_buffer, PT, nchars);
830 #endif
831
832 GAP_SIZE -= nbytes;
833 GPT += nchars;
834 ZV += nchars;
835 Z += nchars;
836 GPT_BYTE += nbytes;
837 ZV_BYTE += nbytes;
838 Z_BYTE += nbytes;
839 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
840 adjust_overlays_for_insert (PT, nchars);
841 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes,
842 before_markers);
843 adjust_point (nchars, nbytes);
844
845 if (GPT_BYTE < GPT)
846 abort ();
847
848 #ifdef USE_TEXT_PROPERTIES
849 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
850 Fset_text_properties (make_number (PT - nchars), make_number (PT),
851 Qnil, Qnil);
852 #endif
853 }
854 \f
855 /* Insert the part of the text of STRING, a Lisp object assumed to be
856 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
857 starting at position POS / POS_BYTE. If the text of STRING has properties,
858 copy them into the buffer.
859
860 It does not work to use `insert' for this, because a GC could happen
861 before we bcopy the stuff into the buffer, and relocate the string
862 without insert noticing. */
863
864 void
865 insert_from_string (string, pos, pos_byte, length, length_byte, inherit)
866 Lisp_Object string;
867 register int pos, pos_byte, length, length_byte;
868 int inherit;
869 {
870 if (length > 0)
871 {
872 int opoint = PT;
873 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
874 inherit, 0);
875 signal_after_change (opoint, 0, PT - opoint);
876 }
877 }
878
879 /* Like `insert_from_string' except that all markers pointing
880 at the place where the insertion happens are adjusted to point after it. */
881
882 void
883 insert_from_string_before_markers (string, pos, pos_byte,
884 length, length_byte, inherit)
885 Lisp_Object string;
886 register int pos, pos_byte, length, length_byte;
887 int inherit;
888 {
889 if (length > 0)
890 {
891 int opoint = PT;
892 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
893 inherit, 1);
894 signal_after_change (opoint, 0, PT - opoint);
895 }
896 }
897
898 /* Subroutine of the insertion functions above. */
899
900 static void
901 insert_from_string_1 (string, pos, pos_byte, nchars, nbytes,
902 inherit, before_markers)
903 Lisp_Object string;
904 register int pos, pos_byte, nchars, nbytes;
905 int inherit, before_markers;
906 {
907 register Lisp_Object temp;
908 struct gcpro gcpro1;
909 int outgoing_nbytes = nbytes;
910
911 /* Make OUTGOING_NBYTES describe the text
912 as it will be inserted in this buffer. */
913
914 if (NILP (current_buffer->enable_multibyte_characters))
915 outgoing_nbytes = nchars;
916 else if (nchars == nbytes)
917 outgoing_nbytes
918 = count_size_as_multibyte (&XSTRING (string)->data[pos_byte],
919 nbytes);
920
921 /* Make sure point-max won't overflow after this insertion. */
922 XSETINT (temp, outgoing_nbytes + Z);
923 if (outgoing_nbytes + Z != XINT (temp))
924 error ("Maximum buffer size exceeded");
925
926 GCPRO1 (string);
927 prepare_to_modify_buffer (PT, PT, NULL);
928
929 if (PT != GPT)
930 move_gap_both (PT, PT_BYTE);
931 if (GAP_SIZE < nbytes)
932 make_gap (outgoing_nbytes - GAP_SIZE);
933
934 record_insert (PT, nchars);
935 MODIFF++;
936 UNGCPRO;
937
938 /* Copy the string text into the buffer, perhaps converting
939 between single-byte and multibyte. */
940 copy_text (XSTRING (string)->data + pos_byte, GPT_ADDR, nbytes,
941 /* If these are equal, it is a single-byte string.
942 Its chars are either ASCII, in which case copy_text
943 won't change it, or single-byte non-ASCII chars,
944 that need to be changed. */
945 nchars != nbytes,
946 ! NILP (current_buffer->enable_multibyte_characters));
947
948 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
949 offset_intervals (current_buffer, PT, nchars);
950
951 GAP_SIZE -= outgoing_nbytes;
952 GPT += nchars;
953 ZV += nchars;
954 Z += nchars;
955 GPT_BYTE += outgoing_nbytes;
956 ZV_BYTE += outgoing_nbytes;
957 Z_BYTE += outgoing_nbytes;
958 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
959 adjust_overlays_for_insert (PT, nchars);
960 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
961 PT_BYTE + outgoing_nbytes,
962 before_markers);
963
964 if (GPT_BYTE < GPT)
965 abort ();
966
967 graft_intervals_into_buffer (XSTRING (string)->intervals, PT, nchars,
968 current_buffer, inherit);
969
970 adjust_point (nchars, outgoing_nbytes);
971 }
972 \f
973 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
974 current buffer. If the text in BUF has properties, they are absorbed
975 into the current buffer.
976
977 It does not work to use `insert' for this, because a malloc could happen
978 and relocate BUF's text before the bcopy happens. */
979
980 void
981 insert_from_buffer (buf, charpos, nchars, inherit)
982 struct buffer *buf;
983 int charpos, nchars;
984 int inherit;
985 {
986 if (nchars > 0)
987 {
988 int opoint = PT;
989
990 insert_from_buffer_1 (buf, charpos, nchars, inherit);
991 signal_after_change (opoint, 0, PT - opoint);
992 }
993 }
994
995 static void
996 insert_from_buffer_1 (buf, from, nchars, inherit)
997 struct buffer *buf;
998 int from, nchars;
999 int inherit;
1000 {
1001 register Lisp_Object temp;
1002 int chunk;
1003 int from_byte = buf_charpos_to_bytepos (buf, from);
1004 int to_byte = buf_charpos_to_bytepos (buf, from + nchars);
1005 int incoming_nbytes = to_byte - from_byte;
1006 int outgoing_nbytes = incoming_nbytes;
1007
1008 /* Make OUTGOING_NBYTES describe the text
1009 as it will be inserted in this buffer. */
1010
1011 if (NILP (current_buffer->enable_multibyte_characters))
1012 outgoing_nbytes = nchars;
1013 else if (NILP (buf->enable_multibyte_characters))
1014 outgoing_nbytes
1015 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf, from_byte),
1016 incoming_nbytes);
1017
1018 /* Make sure point-max won't overflow after this insertion. */
1019 XSETINT (temp, outgoing_nbytes + Z);
1020 if (outgoing_nbytes + Z != XINT (temp))
1021 error ("Maximum buffer size exceeded");
1022
1023 prepare_to_modify_buffer (PT, PT, NULL);
1024
1025 if (PT != GPT)
1026 move_gap_both (PT, PT_BYTE);
1027 if (GAP_SIZE < outgoing_nbytes)
1028 make_gap (outgoing_nbytes - GAP_SIZE);
1029
1030 record_insert (PT, nchars);
1031 MODIFF++;
1032
1033 if (from < BUF_GPT (buf))
1034 {
1035 chunk = BUF_GPT_BYTE (buf) - from_byte;
1036 if (chunk > incoming_nbytes)
1037 chunk = incoming_nbytes;
1038 copy_text (BUF_BYTE_ADDRESS (buf, from_byte),
1039 GPT_ADDR, chunk,
1040 ! NILP (buf->enable_multibyte_characters),
1041 ! NILP (current_buffer->enable_multibyte_characters));
1042 }
1043 else
1044 chunk = 0;
1045 if (chunk < incoming_nbytes)
1046 copy_text (BUF_BYTE_ADDRESS (buf, from_byte + chunk),
1047 GPT_ADDR + chunk, incoming_nbytes - chunk,
1048 ! NILP (buf->enable_multibyte_characters),
1049 ! NILP (current_buffer->enable_multibyte_characters));
1050
1051 #ifdef USE_TEXT_PROPERTIES
1052 if (BUF_INTERVALS (current_buffer) != 0)
1053 offset_intervals (current_buffer, PT, nchars);
1054 #endif
1055
1056 GAP_SIZE -= outgoing_nbytes;
1057 GPT += nchars;
1058 ZV += nchars;
1059 Z += nchars;
1060 GPT_BYTE += outgoing_nbytes;
1061 ZV_BYTE += outgoing_nbytes;
1062 Z_BYTE += outgoing_nbytes;
1063 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1064 adjust_overlays_for_insert (PT, nchars);
1065 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1066 PT_BYTE + outgoing_nbytes, 0);
1067 adjust_point (nchars, outgoing_nbytes);
1068
1069 if (GPT_BYTE < GPT)
1070 abort ();
1071
1072 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1073 graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf),
1074 from, nchars),
1075 PT - nchars, nchars,
1076 current_buffer, inherit);
1077 }
1078 \f
1079 /* This function should be called after moving gap to FROM and before
1080 altering LEN chars of text starting from FROM. This adjusts
1081 various position keepers and markers and as if the text is deleted.
1082 Don't forget to call adjust_after_replace after you actually alter
1083 the text. */
1084
1085 void
1086 adjust_before_replace (from, from_byte, to, to_byte)
1087 int from, from_byte, to, to_byte;
1088 {
1089 adjust_markers_for_delete (from, from_byte, to, to_byte);
1090 record_delete (from, to - from);
1091 }
1092
1093 /* This function should be called after altering the text between FROM
1094 and TO to a new text of LEN chars (LEN_BYTE bytes). */
1095
1096 void
1097 adjust_after_replace (from, from_byte, to, to_byte, len, len_byte)
1098 int from, from_byte, to, to_byte, len, len_byte;
1099 {
1100 record_insert (from, len);
1101 if (from < PT)
1102 adjust_point (len - (to - from), len_byte - (to_byte - from_byte));
1103 #ifdef USE_TEXT_PROPERTIES
1104 offset_intervals (current_buffer, PT, len - (to - from));
1105 #endif
1106 adjust_overlays_for_delete (from, to - from);
1107 adjust_overlays_for_insert (from, len);
1108 adjust_markers_for_insert (from, from_byte,
1109 from + len, from_byte + len_byte, 0);
1110 if (len == 0)
1111 evaporate_overlays (from);
1112 MODIFF++;
1113 }
1114
1115 /* Replace the text from character positions FROM to TO with NEW,
1116 If PREPARE is nonzero, call prepare_to_modify_buffer.
1117 If INHERIT, the newly inserted text should inherit text properties
1118 from the surrounding non-deleted text. */
1119
1120 /* Note that this does not yet handle markers quite right.
1121 Also it needs to record a single undo-entry that does a replacement
1122 rather than a separate delete and insert.
1123 That way, undo will also handle markers properly. */
1124
1125 void
1126 replace_range (from, to, new, prepare, inherit)
1127 Lisp_Object new;
1128 int from, to, prepare, inherit;
1129 {
1130 int inschars = XSTRING (new)->size;
1131 int insbytes = XSTRING (new)->size_byte;
1132 int from_byte, to_byte;
1133 int nbytes_del, nchars_del;
1134 register Lisp_Object temp;
1135 struct gcpro gcpro1;
1136
1137 GCPRO1 (new);
1138
1139 if (prepare)
1140 {
1141 int range_length = to - from;
1142 prepare_to_modify_buffer (from, to, &from);
1143 to = from + range_length;
1144 }
1145
1146 UNGCPRO;
1147
1148 /* Make args be valid */
1149 if (from < BEGV)
1150 from = BEGV;
1151 if (to > ZV)
1152 to = ZV;
1153
1154 from_byte = CHAR_TO_BYTE (from);
1155 to_byte = CHAR_TO_BYTE (to);
1156
1157 nchars_del = to - from;
1158 nbytes_del = to_byte - from_byte;
1159
1160 if (nbytes_del <= 0 && insbytes == 0)
1161 return;
1162
1163 /* Make sure point-max won't overflow after this insertion. */
1164 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1165 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1166 error ("Maximum buffer size exceeded");
1167
1168 GCPRO1 (new);
1169
1170 /* Make sure the gap is somewhere in or next to what we are deleting. */
1171 if (from > GPT)
1172 gap_right (from, from_byte);
1173 if (to < GPT)
1174 gap_left (to, to_byte, 0);
1175
1176 /* Relocate all markers pointing into the new, larger gap
1177 to point at the end of the text before the gap.
1178 Do this before recording the deletion,
1179 so that undo handles this after reinserting the text. */
1180 adjust_markers_for_delete (from, from_byte, to, to_byte);
1181
1182 record_delete (from, nchars_del);
1183
1184 GAP_SIZE += nbytes_del;
1185 ZV -= nchars_del;
1186 Z -= nchars_del;
1187 ZV_BYTE -= nbytes_del;
1188 Z_BYTE -= nbytes_del;
1189 GPT = from;
1190 GPT_BYTE = from_byte;
1191 *(GPT_ADDR) = 0; /* Put an anchor. */
1192
1193 if (GPT_BYTE < GPT)
1194 abort ();
1195
1196 if (GPT - BEG < beg_unchanged)
1197 beg_unchanged = GPT - BEG;
1198 if (Z - GPT < end_unchanged)
1199 end_unchanged = Z - GPT;
1200
1201 if (GAP_SIZE < insbytes)
1202 make_gap (insbytes - GAP_SIZE);
1203
1204 record_insert (from, inschars);
1205
1206 bcopy (XSTRING (new)->data, GPT_ADDR, insbytes);
1207
1208 /* Relocate point as if it were a marker. */
1209 if (from < PT)
1210 adjust_point (from + inschars - (PT < to ? PT : to),
1211 (from_byte + insbytes
1212 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
1213
1214 #ifdef USE_TEXT_PROPERTIES
1215 offset_intervals (current_buffer, PT, inschars - nchars_del);
1216 #endif
1217
1218 GAP_SIZE -= insbytes;
1219 GPT += inschars;
1220 ZV += inschars;
1221 Z += inschars;
1222 GPT_BYTE += insbytes;
1223 ZV_BYTE += insbytes;
1224 ZV_BYTE += insbytes;
1225 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1226
1227 if (GPT_BYTE < GPT)
1228 abort ();
1229
1230 /* Adjust the overlay center as needed. This must be done after
1231 adjusting the markers that bound the overlays. */
1232 adjust_overlays_for_delete (from, nchars_del);
1233 adjust_overlays_for_insert (from, inschars);
1234 adjust_markers_for_insert (from, from_byte, from + inschars,
1235 from_byte + insbytes, 0);
1236
1237 #ifdef USE_TEXT_PROPERTIES
1238 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1239 graft_intervals_into_buffer (XSTRING (new)->intervals, from,
1240 inschars, current_buffer, inherit);
1241 #endif
1242
1243 if (insbytes == 0)
1244 evaporate_overlays (from);
1245
1246 MODIFF++;
1247 UNGCPRO;
1248
1249 signal_after_change (from, nchars_del, inschars);
1250 }
1251 \f
1252 /* Delete characters in current buffer
1253 from FROM up to (but not including) TO.
1254 If TO comes before FROM, we delete nothing. */
1255
1256 void
1257 del_range (from, to)
1258 register int from, to;
1259 {
1260 del_range_1 (from, to, 1);
1261 }
1262
1263 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
1264
1265 void
1266 del_range_1 (from, to, prepare)
1267 int from, to, prepare;
1268 {
1269 int from_byte, to_byte;
1270
1271 /* Make args be valid */
1272 if (from < BEGV)
1273 from = BEGV;
1274 if (to > ZV)
1275 to = ZV;
1276
1277 if (to <= from)
1278 return;
1279
1280 if (prepare)
1281 {
1282 int range_length = to - from;
1283 prepare_to_modify_buffer (from, to, &from);
1284 to = from + range_length;
1285 }
1286
1287 from_byte = CHAR_TO_BYTE (from);
1288 to_byte = CHAR_TO_BYTE (to);
1289
1290 del_range_2 (from, to, from_byte, to_byte);
1291 }
1292
1293 /* Like del_range_1 but args are byte positions, not char positions. */
1294
1295 void
1296 del_range_byte (from_byte, to_byte, prepare)
1297 int from_byte, to_byte, prepare;
1298 {
1299 int from, to;
1300
1301 /* Make args be valid */
1302 if (from_byte < BEGV_BYTE)
1303 from_byte = BEGV_BYTE;
1304 if (to_byte > ZV_BYTE)
1305 to_byte = ZV_BYTE;
1306
1307 if (to_byte <= from_byte)
1308 return;
1309
1310 from = BYTE_TO_CHAR (from_byte);
1311 to = BYTE_TO_CHAR (to_byte);
1312
1313 if (prepare)
1314 {
1315 int old_from = from, old_to = Z - to;
1316 int range_length = to - from;
1317 prepare_to_modify_buffer (from, to, &from);
1318 to = from + range_length;
1319
1320 if (old_from != from)
1321 from_byte = CHAR_TO_BYTE (from);
1322 if (old_to == Z - to)
1323 to_byte = CHAR_TO_BYTE (to);
1324 }
1325
1326 del_range_2 (from, to, from_byte, to_byte);
1327 }
1328
1329 /* Like del_range_1, but positions are specified both as charpos
1330 and bytepos. */
1331
1332 void
1333 del_range_both (from, to, from_byte, to_byte, prepare)
1334 int from, to, from_byte, to_byte, prepare;
1335 {
1336 /* Make args be valid */
1337 if (from_byte < BEGV_BYTE)
1338 from_byte = BEGV_BYTE;
1339 if (to_byte > ZV_BYTE)
1340 to_byte = ZV_BYTE;
1341
1342 if (to_byte <= from_byte)
1343 return;
1344
1345 if (from < BEGV)
1346 from = BEGV;
1347 if (to > ZV)
1348 to = ZV;
1349
1350 if (prepare)
1351 {
1352 int old_from = from, old_to = Z - to;
1353 int range_length = to - from;
1354 prepare_to_modify_buffer (from, to, &from);
1355 to = from + range_length;
1356
1357 if (old_from != from)
1358 from_byte = CHAR_TO_BYTE (from);
1359 if (old_to == Z - to)
1360 to_byte = CHAR_TO_BYTE (to);
1361 }
1362
1363 del_range_2 (from, to, from_byte, to_byte);
1364 }
1365
1366 /* Delete a range of text, specified both as character positions
1367 and byte positions. FROM and TO are character positions,
1368 while FROM_BYTE and TO_BYTE are byte positions. */
1369
1370 void
1371 del_range_2 (from, to, from_byte, to_byte)
1372 int from, to, from_byte, to_byte;
1373 {
1374 register int nbytes_del, nchars_del;
1375
1376 nchars_del = to - from;
1377 nbytes_del = to_byte - from_byte;
1378
1379 /* Make sure the gap is somewhere in or next to what we are deleting. */
1380 if (from > GPT)
1381 gap_right (from, from_byte);
1382 if (to < GPT)
1383 gap_left (to, to_byte, 0);
1384
1385 /* Relocate all markers pointing into the new, larger gap
1386 to point at the end of the text before the gap.
1387 Do this before recording the deletion,
1388 so that undo handles this after reinserting the text. */
1389 adjust_markers_for_delete (from, from_byte, to, to_byte);
1390
1391 record_delete (from, nchars_del);
1392 MODIFF++;
1393
1394 /* Relocate point as if it were a marker. */
1395 if (from < PT)
1396 adjust_point (from - (PT < to ? PT : to),
1397 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte));
1398
1399 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1400 offset_intervals (current_buffer, from, - nchars_del);
1401
1402 /* Adjust the overlay center as needed. This must be done after
1403 adjusting the markers that bound the overlays. */
1404 adjust_overlays_for_delete (from_byte, nchars_del);
1405
1406 GAP_SIZE += nbytes_del;
1407 ZV_BYTE -= nbytes_del;
1408 Z_BYTE -= nbytes_del;
1409 ZV -= nchars_del;
1410 Z -= nchars_del;
1411 GPT = from;
1412 GPT_BYTE = from_byte;
1413 *(GPT_ADDR) = 0; /* Put an anchor. */
1414
1415 if (GPT_BYTE < GPT)
1416 abort ();
1417
1418 if (GPT - BEG < beg_unchanged)
1419 beg_unchanged = GPT - BEG;
1420 if (Z - GPT < end_unchanged)
1421 end_unchanged = Z - GPT;
1422
1423 evaporate_overlays (from);
1424 signal_after_change (from, nchars_del, 0);
1425 }
1426 \f
1427 /* Call this if you're about to change the region of BUFFER from
1428 character positions START to END. This checks the read-only
1429 properties of the region, calls the necessary modification hooks,
1430 and warns the next redisplay that it should pay attention to that
1431 area. */
1432
1433 void
1434 modify_region (buffer, start, end)
1435 struct buffer *buffer;
1436 int start, end;
1437 {
1438 struct buffer *old_buffer = current_buffer;
1439
1440 if (buffer != old_buffer)
1441 set_buffer_internal (buffer);
1442
1443 prepare_to_modify_buffer (start, end, NULL);
1444
1445 if (start - 1 < beg_unchanged
1446 || (unchanged_modified == MODIFF
1447 && overlay_unchanged_modified == OVERLAY_MODIFF))
1448 beg_unchanged = start - 1;
1449 if (Z - end < end_unchanged
1450 || (unchanged_modified == MODIFF
1451 && overlay_unchanged_modified == OVERLAY_MODIFF))
1452 end_unchanged = Z - end;
1453
1454 if (MODIFF <= SAVE_MODIFF)
1455 record_first_change ();
1456 MODIFF++;
1457
1458 buffer->point_before_scroll = Qnil;
1459
1460 if (buffer != old_buffer)
1461 set_buffer_internal (old_buffer);
1462 }
1463 \f
1464 /* Check that it is okay to modify the buffer between START and END,
1465 which are char positions.
1466
1467 Run the before-change-function, if any. If intervals are in use,
1468 verify that the text to be modified is not read-only, and call
1469 any modification properties the text may have.
1470
1471 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1472 by holding its value temporarily in a marker. */
1473
1474 void
1475 prepare_to_modify_buffer (start, end, preserve_ptr)
1476 int start, end;
1477 int *preserve_ptr;
1478 {
1479 if (!NILP (current_buffer->read_only))
1480 Fbarf_if_buffer_read_only ();
1481
1482 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1483 if (BUF_INTERVALS (current_buffer) != 0)
1484 {
1485 if (preserve_ptr)
1486 {
1487 Lisp_Object preserve_marker;
1488 struct gcpro gcpro1;
1489 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
1490 GCPRO1 (preserve_marker);
1491 verify_interval_modification (current_buffer, start, end);
1492 *preserve_ptr = marker_position (preserve_marker);
1493 unchain_marker (preserve_marker);
1494 UNGCPRO;
1495 }
1496 else
1497 verify_interval_modification (current_buffer, start, end);
1498 }
1499
1500 #ifdef CLASH_DETECTION
1501 if (!NILP (current_buffer->file_truename)
1502 /* Make binding buffer-file-name to nil effective. */
1503 && !NILP (current_buffer->filename)
1504 && SAVE_MODIFF >= MODIFF)
1505 lock_file (current_buffer->file_truename);
1506 #else
1507 /* At least warn if this file has changed on disk since it was visited. */
1508 if (!NILP (current_buffer->filename)
1509 && SAVE_MODIFF >= MODIFF
1510 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
1511 && !NILP (Ffile_exists_p (current_buffer->filename)))
1512 call1 (intern ("ask-user-about-supersession-threat"),
1513 current_buffer->filename);
1514 #endif /* not CLASH_DETECTION */
1515
1516 signal_before_change (start, end, preserve_ptr);
1517
1518 if (current_buffer->newline_cache)
1519 invalidate_region_cache (current_buffer,
1520 current_buffer->newline_cache,
1521 start - BEG, Z - end);
1522 if (current_buffer->width_run_cache)
1523 invalidate_region_cache (current_buffer,
1524 current_buffer->width_run_cache,
1525 start - BEG, Z - end);
1526
1527 Vdeactivate_mark = Qt;
1528 }
1529 \f
1530 /* These macros work with an argument named `preserve_ptr'
1531 and a local variable named `preserve_marker'. */
1532
1533 #define PRESERVE_VALUE \
1534 if (preserve_ptr && NILP (preserve_marker)) \
1535 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
1536
1537 #define RESTORE_VALUE \
1538 if (! NILP (preserve_marker)) \
1539 { \
1540 *preserve_ptr = marker_position (preserve_marker); \
1541 unchain_marker (preserve_marker); \
1542 }
1543
1544 #define PRESERVE_START_END \
1545 if (NILP (start_marker)) \
1546 start_marker = Fcopy_marker (start, Qnil); \
1547 if (NILP (end_marker)) \
1548 end_marker = Fcopy_marker (end, Qnil);
1549
1550 #define FETCH_START \
1551 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
1552
1553 #define FETCH_END \
1554 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
1555
1556 /* Signal a change to the buffer immediately before it happens.
1557 START_INT and END_INT are the bounds of the text to be changed.
1558
1559 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1560 by holding its value temporarily in a marker. */
1561
1562 void
1563 signal_before_change (start_int, end_int, preserve_ptr)
1564 int start_int, end_int;
1565 int *preserve_ptr;
1566 {
1567 Lisp_Object start, end;
1568 Lisp_Object start_marker, end_marker;
1569 Lisp_Object preserve_marker;
1570 struct gcpro gcpro1, gcpro2, gcpro3;
1571
1572 start = make_number (start_int);
1573 end = make_number (end_int);
1574 preserve_marker = Qnil;
1575 start_marker = Qnil;
1576 end_marker = Qnil;
1577 GCPRO3 (preserve_marker, start_marker, end_marker);
1578
1579 /* If buffer is unmodified, run a special hook for that case. */
1580 if (SAVE_MODIFF >= MODIFF
1581 && !NILP (Vfirst_change_hook)
1582 && !NILP (Vrun_hooks))
1583 {
1584 PRESERVE_VALUE;
1585 PRESERVE_START_END;
1586 call1 (Vrun_hooks, Qfirst_change_hook);
1587 }
1588
1589 /* Run the before-change-function if any.
1590 We don't bother "binding" this variable to nil
1591 because it is obsolete anyway and new code should not use it. */
1592 if (!NILP (Vbefore_change_function))
1593 {
1594 PRESERVE_VALUE;
1595 PRESERVE_START_END;
1596 call2 (Vbefore_change_function, FETCH_START, FETCH_END);
1597 }
1598
1599 /* Now run the before-change-functions if any. */
1600 if (!NILP (Vbefore_change_functions))
1601 {
1602 Lisp_Object args[3];
1603 Lisp_Object before_change_functions;
1604 Lisp_Object after_change_functions;
1605 struct gcpro gcpro1, gcpro2;
1606
1607 PRESERVE_VALUE;
1608 PRESERVE_START_END;
1609
1610 /* "Bind" before-change-functions and after-change-functions
1611 to nil--but in a way that errors don't know about.
1612 That way, if there's an error in them, they will stay nil. */
1613 before_change_functions = Vbefore_change_functions;
1614 after_change_functions = Vafter_change_functions;
1615 Vbefore_change_functions = Qnil;
1616 Vafter_change_functions = Qnil;
1617 GCPRO2 (before_change_functions, after_change_functions);
1618
1619 /* Actually run the hook functions. */
1620 args[0] = Qbefore_change_functions;
1621 args[1] = FETCH_START;
1622 args[2] = FETCH_END;
1623 run_hook_list_with_args (before_change_functions, 3, args);
1624
1625 /* "Unbind" the variables we "bound" to nil. */
1626 Vbefore_change_functions = before_change_functions;
1627 Vafter_change_functions = after_change_functions;
1628 UNGCPRO;
1629 }
1630
1631 if (!NILP (current_buffer->overlays_before)
1632 || !NILP (current_buffer->overlays_after))
1633 {
1634 PRESERVE_VALUE;
1635 report_overlay_modification (FETCH_START, FETCH_END, 0,
1636 FETCH_START, FETCH_END, Qnil);
1637 }
1638
1639 if (! NILP (start_marker))
1640 free_marker (start_marker);
1641 if (! NILP (end_marker))
1642 free_marker (end_marker);
1643 RESTORE_VALUE;
1644 UNGCPRO;
1645 }
1646
1647 /* Signal a change immediately after it happens.
1648 CHARPOS is the character position of the start of the changed text.
1649 LENDEL is the number of characters of the text before the change.
1650 (Not the whole buffer; just the part that was changed.)
1651 LENINS is the number of characters in that part of the text
1652 after the change. */
1653
1654 void
1655 signal_after_change (charpos, lendel, lenins)
1656 int charpos, lendel, lenins;
1657 {
1658 /* If we are deferring calls to the after-change functions
1659 and there are no before-change functions,
1660 just record the args that we were going to use. */
1661 if (! NILP (Vcombine_after_change_calls)
1662 && NILP (Vbefore_change_function) && NILP (Vbefore_change_functions)
1663 && NILP (current_buffer->overlays_before)
1664 && NILP (current_buffer->overlays_after))
1665 {
1666 Lisp_Object elt;
1667
1668 if (!NILP (combine_after_change_list)
1669 && current_buffer != XBUFFER (combine_after_change_buffer))
1670 Fcombine_after_change_execute ();
1671
1672 elt = Fcons (make_number (charpos - BEG),
1673 Fcons (make_number (Z - (charpos - lendel + lenins)),
1674 Fcons (make_number (lenins - lendel), Qnil)));
1675 combine_after_change_list
1676 = Fcons (elt, combine_after_change_list);
1677 combine_after_change_buffer = Fcurrent_buffer ();
1678
1679 return;
1680 }
1681
1682 if (!NILP (combine_after_change_list))
1683 Fcombine_after_change_execute ();
1684
1685 /* Run the after-change-function if any.
1686 We don't bother "binding" this variable to nil
1687 because it is obsolete anyway and new code should not use it. */
1688 if (!NILP (Vafter_change_function))
1689 call3 (Vafter_change_function,
1690 make_number (charpos), make_number (charpos + lenins),
1691 make_number (lendel));
1692
1693 if (!NILP (Vafter_change_functions))
1694 {
1695 Lisp_Object args[4];
1696 Lisp_Object before_change_functions;
1697 Lisp_Object after_change_functions;
1698 struct gcpro gcpro1, gcpro2;
1699
1700 /* "Bind" before-change-functions and after-change-functions
1701 to nil--but in a way that errors don't know about.
1702 That way, if there's an error in them, they will stay nil. */
1703 before_change_functions = Vbefore_change_functions;
1704 after_change_functions = Vafter_change_functions;
1705 Vbefore_change_functions = Qnil;
1706 Vafter_change_functions = Qnil;
1707 GCPRO2 (before_change_functions, after_change_functions);
1708
1709 /* Actually run the hook functions. */
1710 args[0] = Qafter_change_functions;
1711 XSETFASTINT (args[1], charpos);
1712 XSETFASTINT (args[2], charpos + lenins);
1713 XSETFASTINT (args[3], lendel);
1714 run_hook_list_with_args (after_change_functions,
1715 4, args);
1716
1717 /* "Unbind" the variables we "bound" to nil. */
1718 Vbefore_change_functions = before_change_functions;
1719 Vafter_change_functions = after_change_functions;
1720 UNGCPRO;
1721 }
1722
1723 if (!NILP (current_buffer->overlays_before)
1724 || !NILP (current_buffer->overlays_after))
1725 report_overlay_modification (make_number (charpos),
1726 make_number (charpos + lenins),
1727 1,
1728 make_number (charpos),
1729 make_number (charpos + lenins),
1730 make_number (lendel));
1731
1732 /* After an insertion, call the text properties
1733 insert-behind-hooks or insert-in-front-hooks. */
1734 if (lendel == 0)
1735 report_interval_modification (charpos, charpos + lenins);
1736 }
1737
1738 Lisp_Object
1739 Fcombine_after_change_execute_1 (val)
1740 Lisp_Object val;
1741 {
1742 Vcombine_after_change_calls = val;
1743 return val;
1744 }
1745
1746 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
1747 Scombine_after_change_execute, 0, 0, 0,
1748 "This function is for use internally in `combine-after-change-calls'.")
1749 ()
1750 {
1751 register Lisp_Object val;
1752 int count = specpdl_ptr - specpdl;
1753 int beg, end, change;
1754 int begpos, endpos;
1755 Lisp_Object tail;
1756
1757 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
1758
1759 Fset_buffer (combine_after_change_buffer);
1760
1761 /* # chars unchanged at beginning of buffer. */
1762 beg = Z - BEG;
1763 /* # chars unchanged at end of buffer. */
1764 end = beg;
1765 /* Total amount of insertion (negative for deletion). */
1766 change = 0;
1767
1768 /* Scan the various individual changes,
1769 accumulating the range info in BEG, END and CHANGE. */
1770 for (tail = combine_after_change_list; CONSP (tail);
1771 tail = XCONS (tail)->cdr)
1772 {
1773 Lisp_Object elt;
1774 int thisbeg, thisend, thischange;
1775
1776 /* Extract the info from the next element. */
1777 elt = XCONS (tail)->car;
1778 if (! CONSP (elt))
1779 continue;
1780 thisbeg = XINT (XCONS (elt)->car);
1781
1782 elt = XCONS (elt)->cdr;
1783 if (! CONSP (elt))
1784 continue;
1785 thisend = XINT (XCONS (elt)->car);
1786
1787 elt = XCONS (elt)->cdr;
1788 if (! CONSP (elt))
1789 continue;
1790 thischange = XINT (XCONS (elt)->car);
1791
1792 /* Merge this range into the accumulated range. */
1793 change += thischange;
1794 if (thisbeg < beg)
1795 beg = thisbeg;
1796 if (thisend < end)
1797 end = thisend;
1798 }
1799
1800 /* Get the current start and end positions of the range
1801 that was changed. */
1802 begpos = BEG + beg;
1803 endpos = Z - end;
1804
1805 /* We are about to handle these, so discard them. */
1806 combine_after_change_list = Qnil;
1807
1808 /* Now run the after-change functions for real.
1809 Turn off the flag that defers them. */
1810 record_unwind_protect (Fcombine_after_change_execute_1,
1811 Vcombine_after_change_calls);
1812 signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
1813
1814 return unbind_to (count, val);
1815 }
1816 \f
1817 syms_of_insdel ()
1818 {
1819 staticpro (&combine_after_change_list);
1820 combine_after_change_list = Qnil;
1821
1822 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
1823 "Used internally by the `combine-after-change-calls' macro.");
1824 Vcombine_after_change_calls = Qnil;
1825
1826 defsubr (&Scombine_after_change_execute);
1827 }