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