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