Fix more GCC strict-aliasing warnings.
[emacs.git] / src / insdel.c
blobb76a2d2271a90078708867a5a94fabbedfb839ba
1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
4 Free Software Foundation, Inc.
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 #include <config.h>
23 #include <setjmp.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"
32 #ifndef NULL
33 #define NULL 0
34 #endif
36 static void insert_from_string_1 (Lisp_Object string,
37 EMACS_INT pos, EMACS_INT pos_byte,
38 EMACS_INT nchars, EMACS_INT nbytes,
39 int inherit, int before_markers);
40 static void insert_from_buffer_1 (struct buffer *buf,
41 EMACS_INT from, EMACS_INT nchars,
42 int inherit);
43 static void gap_left (EMACS_INT charpos, EMACS_INT bytepos, int newgap);
44 static void gap_right (EMACS_INT charpos, EMACS_INT bytepos);
45 static void adjust_markers_gap_motion (EMACS_INT from, EMACS_INT to,
46 EMACS_INT amount);
47 static void adjust_markers_for_insert (EMACS_INT from, EMACS_INT from_byte,
48 EMACS_INT to, EMACS_INT to_byte,
49 int before_markers);
50 static void adjust_markers_for_replace (EMACS_INT, EMACS_INT, EMACS_INT,
51 EMACS_INT, EMACS_INT, EMACS_INT);
52 static void adjust_point (EMACS_INT nchars, EMACS_INT nbytes);
54 Lisp_Object Fcombine_after_change_execute ();
56 /* Non-nil means don't call the after-change-functions right away,
57 just record an element in Vcombine_after_change_calls_list. */
58 Lisp_Object Vcombine_after_change_calls;
60 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
61 describing changes which happened while combine_after_change_calls
62 was nonzero. We use this to decide how to call them
63 once the deferral ends.
65 In each element.
66 BEG-UNCHANGED is the number of chars before the changed range.
67 END-UNCHANGED is the number of chars after the changed range,
68 and CHANGE-AMOUNT is the number of characters inserted by the change
69 (negative for a deletion). */
70 Lisp_Object combine_after_change_list;
72 /* Buffer which combine_after_change_list is about. */
73 Lisp_Object combine_after_change_buffer;
75 Lisp_Object Qinhibit_modification_hooks;
78 /* Check all markers in the current buffer, looking for something invalid. */
80 static int check_markers_debug_flag;
82 #define CHECK_MARKERS() \
83 if (check_markers_debug_flag) \
84 check_markers (); \
85 else
87 void
88 check_markers ()
90 register struct Lisp_Marker *tail;
91 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
93 for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
95 if (tail->buffer->text != current_buffer->text)
96 abort ();
97 if (tail->charpos > Z)
98 abort ();
99 if (tail->bytepos > Z_BYTE)
100 abort ();
101 if (multibyte && ! CHAR_HEAD_P (FETCH_BYTE (tail->bytepos)))
102 abort ();
106 /* Move gap to position CHARPOS.
107 Note that this can quit! */
109 void
110 move_gap (EMACS_INT charpos)
112 move_gap_both (charpos, charpos_to_bytepos (charpos));
115 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
116 Note that this can quit! */
118 void
119 move_gap_both (EMACS_INT charpos, EMACS_INT bytepos)
121 if (bytepos < GPT_BYTE)
122 gap_left (charpos, bytepos, 0);
123 else if (bytepos > GPT_BYTE)
124 gap_right (charpos, bytepos);
127 /* Move the gap to a position less than the current GPT.
128 BYTEPOS describes the new position as a byte position,
129 and CHARPOS is the corresponding char position.
130 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
132 static void
133 gap_left (EMACS_INT charpos, EMACS_INT bytepos, int newgap)
135 register unsigned char *to, *from;
136 register EMACS_INT i;
137 EMACS_INT new_s1;
139 if (!newgap)
140 BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
142 i = GPT_BYTE;
143 to = GAP_END_ADDR;
144 from = GPT_ADDR;
145 new_s1 = GPT_BYTE;
147 /* Now copy the characters. To move the gap down,
148 copy characters up. */
150 while (1)
152 /* I gets number of characters left to copy. */
153 i = new_s1 - bytepos;
154 if (i == 0)
155 break;
156 /* If a quit is requested, stop copying now.
157 Change BYTEPOS to be where we have actually moved the gap to. */
158 if (QUITP)
160 bytepos = new_s1;
161 charpos = BYTE_TO_CHAR (bytepos);
162 break;
164 /* Move at most 32000 chars before checking again for a quit. */
165 if (i > 32000)
166 i = 32000;
167 #ifdef GAP_USE_BCOPY
168 if (i >= 128
169 /* bcopy is safe if the two areas of memory do not overlap
170 or on systems where bcopy is always safe for moving upward. */
171 && (BCOPY_UPWARD_SAFE
172 || to - from >= 128))
174 /* If overlap is not safe, avoid it by not moving too many
175 characters at once. */
176 if (!BCOPY_UPWARD_SAFE && i > to - from)
177 i = to - from;
178 new_s1 -= i;
179 from -= i, to -= i;
180 bcopy (from, to, i);
182 else
183 #endif
185 new_s1 -= i;
186 while (--i >= 0)
187 *--to = *--from;
191 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
192 BYTEPOS is where the loop above stopped, which may be what was specified
193 or may be where a quit was detected. */
194 adjust_markers_gap_motion (bytepos, GPT_BYTE, GAP_SIZE);
195 GPT_BYTE = bytepos;
196 GPT = charpos;
197 if (bytepos < charpos)
198 abort ();
199 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
200 QUIT;
203 /* Move the gap to a position greater than the current GPT.
204 BYTEPOS describes the new position as a byte position,
205 and CHARPOS is the corresponding char position. */
207 static void
208 gap_right (EMACS_INT charpos, EMACS_INT bytepos)
210 register unsigned char *to, *from;
211 register EMACS_INT i;
212 EMACS_INT new_s1;
214 BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
216 i = GPT_BYTE;
217 from = GAP_END_ADDR;
218 to = GPT_ADDR;
219 new_s1 = GPT_BYTE;
221 /* Now copy the characters. To move the gap up,
222 copy characters down. */
224 while (1)
226 /* I gets number of characters left to copy. */
227 i = bytepos - new_s1;
228 if (i == 0)
229 break;
230 /* If a quit is requested, stop copying now.
231 Change BYTEPOS to be where we have actually moved the gap to. */
232 if (QUITP)
234 bytepos = new_s1;
235 charpos = BYTE_TO_CHAR (bytepos);
236 break;
238 /* Move at most 32000 chars before checking again for a quit. */
239 if (i > 32000)
240 i = 32000;
241 #ifdef GAP_USE_BCOPY
242 if (i >= 128
243 /* bcopy is safe if the two areas of memory do not overlap
244 or on systems where bcopy is always safe for moving downward. */
245 && (BCOPY_DOWNWARD_SAFE
246 || from - to >= 128))
248 /* If overlap is not safe, avoid it by not moving too many
249 characters at once. */
250 if (!BCOPY_DOWNWARD_SAFE && i > from - to)
251 i = from - to;
252 new_s1 += i;
253 bcopy (from, to, i);
254 from += i, to += i;
256 else
257 #endif
259 new_s1 += i;
260 while (--i >= 0)
261 *to++ = *from++;
265 adjust_markers_gap_motion (GPT_BYTE + GAP_SIZE, bytepos + GAP_SIZE,
266 - GAP_SIZE);
267 GPT = charpos;
268 GPT_BYTE = bytepos;
269 if (bytepos < charpos)
270 abort ();
271 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
272 QUIT;
275 /* Add AMOUNT to the byte position of every marker in the current buffer
276 whose current byte position is between FROM (exclusive) and TO (inclusive).
278 Also, any markers past the outside of that interval, in the direction
279 of adjustment, are first moved back to the near end of the interval
280 and then adjusted by AMOUNT.
282 When the latter adjustment is done, if AMOUNT is negative,
283 we record the adjustment for undo. (This case happens only for
284 deletion.)
286 The markers' character positions are not altered,
287 because gap motion does not affect character positions. */
289 int adjust_markers_test;
291 static void
292 adjust_markers_gap_motion (EMACS_INT from, EMACS_INT to, EMACS_INT amount)
294 /* Now that a marker has a bytepos, not counting the gap,
295 nothing needs to be done here. */
296 #if 0
297 Lisp_Object marker;
298 register struct Lisp_Marker *m;
299 register EMACS_INT mpos;
301 marker = BUF_MARKERS (current_buffer);
303 while (!NILP (marker))
305 m = XMARKER (marker);
306 mpos = m->bytepos;
307 if (amount > 0)
309 if (mpos > to && mpos < to + amount)
311 if (adjust_markers_test)
312 abort ();
313 mpos = to + amount;
316 else
318 /* Here's the case where a marker is inside text being deleted.
319 AMOUNT can be negative for gap motion, too,
320 but then this range contains no markers. */
321 if (mpos > from + amount && mpos <= from)
323 if (adjust_markers_test)
324 abort ();
325 mpos = from + amount;
328 if (mpos > from && mpos <= to)
329 mpos += amount;
330 m->bufpos = mpos;
331 marker = m->chain;
333 #endif
336 /* Adjust all markers for a deletion
337 whose range in bytes is FROM_BYTE to TO_BYTE.
338 The range in charpos is FROM to TO.
340 This function assumes that the gap is adjacent to
341 or inside of the range being deleted. */
343 void
344 adjust_markers_for_delete (EMACS_INT from, EMACS_INT from_byte,
345 EMACS_INT to, EMACS_INT to_byte)
347 Lisp_Object marker;
348 register struct Lisp_Marker *m;
349 register EMACS_INT charpos;
351 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
353 charpos = m->charpos;
355 if (charpos > Z)
356 abort ();
358 /* If the marker is after the deletion,
359 relocate by number of chars / bytes deleted. */
360 if (charpos > to)
362 m->charpos -= to - from;
363 m->bytepos -= to_byte - from_byte;
365 /* Here's the case where a marker is inside text being deleted. */
366 else if (charpos > from)
368 if (! m->insertion_type)
369 { /* Normal markers will end up at the beginning of the
370 re-inserted text after undoing a deletion, and must be
371 adjusted to move them to the correct place. */
372 XSETMISC (marker, m);
373 record_marker_adjustment (marker, from - charpos);
375 else if (charpos < to)
376 { /* Before-insertion markers will automatically move forward
377 upon re-inserting the deleted text, so we have to arrange
378 for them to move backward to the correct position. */
379 XSETMISC (marker, m);
380 record_marker_adjustment (marker, to - charpos);
382 m->charpos = from;
383 m->bytepos = from_byte;
385 /* Here's the case where a before-insertion marker is immediately
386 before the deleted region. */
387 else if (charpos == from && m->insertion_type)
389 /* Undoing the change uses normal insertion, which will
390 incorrectly make MARKER move forward, so we arrange for it
391 to then move backward to the correct place at the beginning
392 of the deleted region. */
393 XSETMISC (marker, m);
394 record_marker_adjustment (marker, to - from);
400 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
401 to TO / TO_BYTE. We have to relocate the charpos of every marker
402 that points after the insertion (but not their bytepos).
404 When a marker points at the insertion point,
405 we advance it if either its insertion-type is t
406 or BEFORE_MARKERS is true. */
408 static void
409 adjust_markers_for_insert (EMACS_INT from, EMACS_INT from_byte,
410 EMACS_INT to, EMACS_INT to_byte, int before_markers)
412 struct Lisp_Marker *m;
413 int adjusted = 0;
414 EMACS_INT nchars = to - from;
415 EMACS_INT nbytes = to_byte - from_byte;
417 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
419 eassert (m->bytepos >= m->charpos
420 && m->bytepos - m->charpos <= Z_BYTE - Z);
422 if (m->bytepos == from_byte)
424 if (m->insertion_type || before_markers)
426 m->bytepos = to_byte;
427 m->charpos = to;
428 if (m->insertion_type)
429 adjusted = 1;
432 else if (m->bytepos > from_byte)
434 m->bytepos += nbytes;
435 m->charpos += nchars;
439 /* Adjusting only markers whose insertion-type is t may result in
440 - disordered start and end in overlays, and
441 - disordered overlays in the slot `overlays_before' of current_buffer. */
442 if (adjusted)
444 fix_start_end_in_overlays(from, to);
445 fix_overlays_before (current_buffer, from, to);
449 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
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. */
459 static void
460 adjust_point (EMACS_INT nchars, EMACS_INT nbytes)
462 SET_BUF_PT_BOTH (current_buffer, PT + nchars, PT_BYTE + nbytes);
463 /* In a single-byte buffer, the two positions must be equal. */
464 eassert (PT_BYTE >= PT && PT_BYTE - PT <= ZV_BYTE - ZV);
467 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
468 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
469 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
470 an insertion. */
472 static void
473 adjust_markers_for_replace (EMACS_INT from, EMACS_INT from_byte,
474 EMACS_INT old_chars, EMACS_INT old_bytes,
475 EMACS_INT new_chars, EMACS_INT new_bytes)
477 register struct Lisp_Marker *m;
478 EMACS_INT prev_to_byte = from_byte + old_bytes;
479 EMACS_INT diff_chars = new_chars - old_chars;
480 EMACS_INT diff_bytes = new_bytes - old_bytes;
482 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
484 if (m->bytepos >= prev_to_byte)
486 m->charpos += diff_chars;
487 m->bytepos += diff_bytes;
489 else if (m->bytepos > from_byte)
491 m->charpos = from;
492 m->bytepos = from_byte;
496 CHECK_MARKERS ();
500 /* Make the gap NBYTES_ADDED bytes longer. */
502 void
503 make_gap_larger (EMACS_INT nbytes_added)
505 Lisp_Object tem;
506 EMACS_INT real_gap_loc;
507 EMACS_INT real_gap_loc_byte;
508 EMACS_INT old_gap_size;
510 /* If we have to get more space, get enough to last a while. */
511 nbytes_added += 2000;
513 { EMACS_INT total_size = Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added;
514 if (total_size < 0
515 /* Don't allow a buffer size that won't fit in a Lisp integer. */
516 || total_size != XINT (make_number (total_size))
517 /* Don't allow a buffer size that won't fit in an int
518 even if it will fit in a Lisp integer.
519 That won't work because so many places still use `int'. */
520 || total_size != (EMACS_INT) (int) total_size)
521 error ("Buffer exceeds maximum size");
524 enlarge_buffer_text (current_buffer, nbytes_added);
526 /* Prevent quitting in move_gap. */
527 tem = Vinhibit_quit;
528 Vinhibit_quit = Qt;
530 real_gap_loc = GPT;
531 real_gap_loc_byte = GPT_BYTE;
532 old_gap_size = GAP_SIZE;
534 /* Call the newly allocated space a gap at the end of the whole space. */
535 GPT = Z + GAP_SIZE;
536 GPT_BYTE = Z_BYTE + GAP_SIZE;
537 GAP_SIZE = nbytes_added;
539 /* Move the new gap down to be consecutive with the end of the old one.
540 This adjusts the markers properly too. */
541 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
543 /* Now combine the two into one large gap. */
544 GAP_SIZE += old_gap_size;
545 GPT = real_gap_loc;
546 GPT_BYTE = real_gap_loc_byte;
548 /* Put an anchor. */
549 *(Z_ADDR) = 0;
551 Vinhibit_quit = tem;
555 /* Make the gap NBYTES_REMOVED bytes shorter. */
557 void
558 make_gap_smaller (EMACS_INT nbytes_removed)
560 Lisp_Object tem;
561 EMACS_INT real_gap_loc;
562 EMACS_INT real_gap_loc_byte;
563 EMACS_INT real_Z;
564 EMACS_INT real_Z_byte;
565 EMACS_INT real_beg_unchanged;
566 EMACS_INT new_gap_size;
568 /* Make sure the gap is at least 20 bytes. */
569 if (GAP_SIZE - nbytes_removed < 20)
570 nbytes_removed = GAP_SIZE - 20;
572 /* Prevent quitting in move_gap. */
573 tem = Vinhibit_quit;
574 Vinhibit_quit = Qt;
576 real_gap_loc = GPT;
577 real_gap_loc_byte = GPT_BYTE;
578 new_gap_size = GAP_SIZE - nbytes_removed;
579 real_Z = Z;
580 real_Z_byte = Z_BYTE;
581 real_beg_unchanged = BEG_UNCHANGED;
583 /* Pretend that the last unwanted part of the gap is the entire gap,
584 and that the first desired part of the gap is part of the buffer
585 text. */
586 bzero (GPT_ADDR, new_gap_size);
587 GPT += new_gap_size;
588 GPT_BYTE += new_gap_size;
589 Z += new_gap_size;
590 Z_BYTE += new_gap_size;
591 GAP_SIZE = nbytes_removed;
593 /* Move the unwanted pretend gap to the end of the buffer. This
594 adjusts the markers properly too. */
595 gap_right (Z, Z_BYTE);
597 enlarge_buffer_text (current_buffer, -nbytes_removed);
599 /* Now restore the desired gap. */
600 GAP_SIZE = new_gap_size;
601 GPT = real_gap_loc;
602 GPT_BYTE = real_gap_loc_byte;
603 Z = real_Z;
604 Z_BYTE = real_Z_byte;
605 BEG_UNCHANGED = real_beg_unchanged;
607 /* Put an anchor. */
608 *(Z_ADDR) = 0;
610 Vinhibit_quit = tem;
613 void
614 make_gap (EMACS_INT nbytes_added)
616 if (nbytes_added >= 0)
617 make_gap_larger (nbytes_added);
618 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
619 else
620 make_gap_smaller (-nbytes_added);
621 #endif
624 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
625 FROM_MULTIBYTE says whether the incoming text is multibyte.
626 TO_MULTIBYTE says whether to store the text as multibyte.
627 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
629 Return the number of bytes stored at TO_ADDR. */
631 EMACS_INT
632 copy_text (const unsigned char *from_addr, unsigned char *to_addr,
633 EMACS_INT nbytes, int from_multibyte, int to_multibyte)
635 if (from_multibyte == to_multibyte)
637 bcopy (from_addr, to_addr, nbytes);
638 return nbytes;
640 else if (from_multibyte)
642 EMACS_INT nchars = 0;
643 EMACS_INT bytes_left = nbytes;
644 Lisp_Object tbl = Qnil;
646 while (bytes_left > 0)
648 int thislen, c;
649 c = STRING_CHAR_AND_LENGTH (from_addr, thislen);
650 if (! ASCII_CHAR_P (c))
651 c &= 0xFF;
652 *to_addr++ = c;
653 from_addr += thislen;
654 bytes_left -= thislen;
655 nchars++;
657 return nchars;
659 else
661 unsigned char *initial_to_addr = to_addr;
663 /* Convert single-byte to multibyte. */
664 while (nbytes > 0)
666 int c = *from_addr++;
668 if (!ASCII_CHAR_P (c))
670 c = BYTE8_TO_CHAR (c);
671 to_addr += CHAR_STRING (c, to_addr);
672 nbytes--;
674 else
675 /* Special case for speed. */
676 *to_addr++ = c, nbytes--;
678 return to_addr - initial_to_addr;
682 /* Return the number of bytes it would take
683 to convert some single-byte text to multibyte.
684 The single-byte text consists of NBYTES bytes at PTR. */
686 EMACS_INT
687 count_size_as_multibyte (const unsigned char *ptr, EMACS_INT nbytes)
689 EMACS_INT i;
690 EMACS_INT outgoing_nbytes = 0;
692 for (i = 0; i < nbytes; i++)
694 unsigned int c = *ptr++;
696 if (ASCII_CHAR_P (c))
697 outgoing_nbytes++;
698 else
700 c = BYTE8_TO_CHAR (c);
701 outgoing_nbytes += CHAR_BYTES (c);
705 return outgoing_nbytes;
708 /* Insert a string of specified length before point.
709 This function judges multibyteness based on
710 enable_multibyte_characters in the current buffer;
711 it never converts between single-byte and multibyte.
713 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
714 prepare_to_modify_buffer could relocate the text. */
716 void
717 insert (const unsigned char *string, EMACS_INT nbytes)
719 if (nbytes > 0)
721 EMACS_INT len = chars_in_text (string, nbytes), opoint;
722 insert_1_both (string, len, nbytes, 0, 1, 0);
723 opoint = PT - len;
724 signal_after_change (opoint, 0, len);
725 update_compositions (opoint, PT, CHECK_BORDER);
729 /* Likewise, but inherit text properties from neighboring characters. */
731 void
732 insert_and_inherit (const unsigned char *string, EMACS_INT nbytes)
734 if (nbytes > 0)
736 EMACS_INT len = chars_in_text (string, nbytes), opoint;
737 insert_1_both (string, len, nbytes, 1, 1, 0);
738 opoint = PT - len;
739 signal_after_change (opoint, 0, len);
740 update_compositions (opoint, PT, CHECK_BORDER);
744 /* Insert the character C before point. Do not inherit text properties. */
746 void
747 insert_char (int c)
749 unsigned char str[MAX_MULTIBYTE_LENGTH];
750 int len;
752 if (! NILP (current_buffer->enable_multibyte_characters))
753 len = CHAR_STRING (c, str);
754 else
756 len = 1;
757 str[0] = c;
760 insert (str, len);
763 /* Insert the null-terminated string S before point. */
765 void
766 insert_string (const char *s)
768 insert (s, strlen (s));
771 /* Like `insert' except that all markers pointing at the place where
772 the insertion happens are adjusted to point after it.
773 Don't use this function to insert part of a Lisp string,
774 since gc could happen and relocate it. */
776 void
777 insert_before_markers (const unsigned char *string, EMACS_INT nbytes)
779 if (nbytes > 0)
781 EMACS_INT len = chars_in_text (string, nbytes), opoint;
782 insert_1_both (string, len, nbytes, 0, 1, 1);
783 opoint = PT - len;
784 signal_after_change (opoint, 0, len);
785 update_compositions (opoint, PT, CHECK_BORDER);
789 /* Likewise, but inherit text properties from neighboring characters. */
791 void
792 insert_before_markers_and_inherit (const unsigned char *string,
793 EMACS_INT nbytes)
795 if (nbytes > 0)
797 EMACS_INT len = chars_in_text (string, nbytes), opoint;
798 insert_1_both (string, len, nbytes, 1, 1, 1);
799 opoint = PT - len;
800 signal_after_change (opoint, 0, len);
801 update_compositions (opoint, PT, CHECK_BORDER);
805 /* Subroutine used by the insert functions above. */
807 void
808 insert_1 (const unsigned char *string, EMACS_INT nbytes,
809 int inherit, int prepare, int before_markers)
811 insert_1_both (string, chars_in_text (string, nbytes), nbytes,
812 inherit, prepare, before_markers);
816 #ifdef BYTE_COMBINING_DEBUG
818 /* See if the bytes before POS/POS_BYTE combine with bytes
819 at the start of STRING to form a single character.
820 If so, return the number of bytes at the start of STRING
821 which combine in this way. Otherwise, return 0. */
824 count_combining_before (const unsigned char *string, EMACS_INT length,
825 EMACS_INT pos, EMACS_INT pos_byte)
827 int len, combining_bytes;
828 const unsigned char *p;
830 if (NILP (current_buffer->enable_multibyte_characters))
831 return 0;
833 /* At first, we can exclude the following cases:
834 (1) STRING[0] can't be a following byte of multibyte sequence.
835 (2) POS is the start of the current buffer.
836 (3) A character before POS is not a multibyte character. */
837 if (length == 0 || CHAR_HEAD_P (*string)) /* case (1) */
838 return 0;
839 if (pos_byte == BEG_BYTE) /* case (2) */
840 return 0;
841 len = 1;
842 p = BYTE_POS_ADDR (pos_byte - 1);
843 while (! CHAR_HEAD_P (*p)) p--, len++;
844 if (! BASE_LEADING_CODE_P (*p)) /* case (3) */
845 return 0;
847 combining_bytes = BYTES_BY_CHAR_HEAD (*p) - len;
848 if (combining_bytes <= 0)
849 /* The character preceding POS is, complete and no room for
850 combining bytes (combining_bytes == 0), or an independent 8-bit
851 character (combining_bytes < 0). */
852 return 0;
854 /* We have a combination situation. Count the bytes at STRING that
855 may combine. */
856 p = string + 1;
857 while (!CHAR_HEAD_P (*p) && p < string + length)
858 p++;
860 return (combining_bytes < p - string ? combining_bytes : p - string);
863 /* See if the bytes after POS/POS_BYTE combine with bytes
864 at the end of STRING to form a single character.
865 If so, return the number of bytes after POS/POS_BYTE
866 which combine in this way. Otherwise, return 0. */
869 count_combining_after (const unsigned char *string,
870 EMACS_INT length, EMACS_INT pos, EMACS_INT pos_byte)
872 EMACS_INT opos_byte = pos_byte;
873 EMACS_INT i;
874 EMACS_INT bytes;
875 unsigned char *bufp;
877 if (NILP (current_buffer->enable_multibyte_characters))
878 return 0;
880 /* At first, we can exclude the following cases:
881 (1) The last byte of STRING is an ASCII.
882 (2) POS is the last of the current buffer.
883 (3) A character at POS can't be a following byte of multibyte
884 character. */
885 if (length > 0 && ASCII_BYTE_P (string[length - 1])) /* case (1) */
886 return 0;
887 if (pos_byte == Z_BYTE) /* case (2) */
888 return 0;
889 bufp = BYTE_POS_ADDR (pos_byte);
890 if (CHAR_HEAD_P (*bufp)) /* case (3) */
891 return 0;
893 i = length - 1;
894 while (i >= 0 && ! CHAR_HEAD_P (string[i]))
896 i--;
898 if (i < 0)
900 /* All characters in STRING are not character head. We must
901 check also preceding bytes at POS. We are sure that the gap
902 is at POS. */
903 unsigned char *p = BEG_ADDR;
904 i = pos_byte - 2;
905 while (i >= 0 && ! CHAR_HEAD_P (p[i]))
906 i--;
907 if (i < 0 || !BASE_LEADING_CODE_P (p[i]))
908 return 0;
910 bytes = BYTES_BY_CHAR_HEAD (p[i]);
911 return (bytes <= pos_byte - 1 - i + length
913 : bytes - (pos_byte - 1 - i + length));
915 if (!BASE_LEADING_CODE_P (string[i]))
916 return 0;
918 bytes = BYTES_BY_CHAR_HEAD (string[i]) - (length - i);
919 bufp++, pos_byte++;
920 while (!CHAR_HEAD_P (*bufp)) bufp++, pos_byte++;
922 return (bytes <= pos_byte - opos_byte ? bytes : pos_byte - opos_byte);
925 #endif
928 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
929 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
930 are the same as in insert_1. */
932 void
933 insert_1_both (const unsigned char *string,
934 EMACS_INT nchars, EMACS_INT nbytes,
935 int inherit, int prepare, int before_markers)
937 if (nchars == 0)
938 return;
940 if (NILP (current_buffer->enable_multibyte_characters))
941 nchars = nbytes;
943 if (prepare)
944 /* Do this before moving and increasing the gap,
945 because the before-change hooks might move the gap
946 or make it smaller. */
947 prepare_to_modify_buffer (PT, PT, NULL);
949 if (PT != GPT)
950 move_gap_both (PT, PT_BYTE);
951 if (GAP_SIZE < nbytes)
952 make_gap (nbytes - GAP_SIZE);
954 #ifdef BYTE_COMBINING_DEBUG
955 if (count_combining_before (string, nbytes, PT, PT_BYTE)
956 || count_combining_after (string, nbytes, PT, PT_BYTE))
957 abort ();
958 #endif
960 /* Record deletion of the surrounding text that combines with
961 the insertion. This, together with recording the insertion,
962 will add up to the right stuff in the undo list. */
963 record_insert (PT, nchars);
964 MODIFF++;
965 CHARS_MODIFF = MODIFF;
967 bcopy (string, GPT_ADDR, nbytes);
969 GAP_SIZE -= nbytes;
970 GPT += nchars;
971 ZV += nchars;
972 Z += nchars;
973 GPT_BYTE += nbytes;
974 ZV_BYTE += nbytes;
975 Z_BYTE += nbytes;
976 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
978 if (GPT_BYTE < GPT)
979 abort ();
981 /* The insert may have been in the unchanged region, so check again. */
982 if (Z - GPT < END_UNCHANGED)
983 END_UNCHANGED = Z - GPT;
985 adjust_overlays_for_insert (PT, nchars);
986 adjust_markers_for_insert (PT, PT_BYTE,
987 PT + nchars, PT_BYTE + nbytes,
988 before_markers);
990 if (BUF_INTERVALS (current_buffer) != 0)
991 offset_intervals (current_buffer, PT, nchars);
993 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
994 set_text_properties (make_number (PT), make_number (PT + nchars),
995 Qnil, Qnil, Qnil);
997 adjust_point (nchars, nbytes);
999 CHECK_MARKERS ();
1002 /* Insert the part of the text of STRING, a Lisp object assumed to be
1003 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1004 starting at position POS / POS_BYTE. If the text of STRING has properties,
1005 copy them into the buffer.
1007 It does not work to use `insert' for this, because a GC could happen
1008 before we bcopy the stuff into the buffer, and relocate the string
1009 without insert noticing. */
1011 void
1012 insert_from_string (Lisp_Object string, EMACS_INT pos, EMACS_INT pos_byte,
1013 EMACS_INT length, EMACS_INT length_byte, int inherit)
1015 EMACS_INT opoint = PT;
1017 if (SCHARS (string) == 0)
1018 return;
1020 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1021 inherit, 0);
1022 signal_after_change (opoint, 0, PT - opoint);
1023 update_compositions (opoint, PT, CHECK_BORDER);
1026 /* Like `insert_from_string' except that all markers pointing
1027 at the place where the insertion happens are adjusted to point after it. */
1029 void
1030 insert_from_string_before_markers (Lisp_Object string,
1031 EMACS_INT pos, EMACS_INT pos_byte,
1032 EMACS_INT length, EMACS_INT length_byte,
1033 int inherit)
1035 EMACS_INT opoint = PT;
1037 if (SCHARS (string) == 0)
1038 return;
1040 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1041 inherit, 1);
1042 signal_after_change (opoint, 0, PT - opoint);
1043 update_compositions (opoint, PT, CHECK_BORDER);
1046 /* Subroutine of the insertion functions above. */
1048 static void
1049 insert_from_string_1 (Lisp_Object string, EMACS_INT pos, EMACS_INT pos_byte,
1050 EMACS_INT nchars, EMACS_INT nbytes,
1051 int inherit, int before_markers)
1053 struct gcpro gcpro1;
1054 EMACS_INT outgoing_nbytes = nbytes;
1055 INTERVAL intervals;
1057 /* Make OUTGOING_NBYTES describe the text
1058 as it will be inserted in this buffer. */
1060 if (NILP (current_buffer->enable_multibyte_characters))
1061 outgoing_nbytes = nchars;
1062 else if (! STRING_MULTIBYTE (string))
1063 outgoing_nbytes
1064 = count_size_as_multibyte (SDATA (string) + pos_byte,
1065 nbytes);
1067 GCPRO1 (string);
1068 /* Do this before moving and increasing the gap,
1069 because the before-change hooks might move the gap
1070 or make it smaller. */
1071 prepare_to_modify_buffer (PT, PT, NULL);
1073 if (PT != GPT)
1074 move_gap_both (PT, PT_BYTE);
1075 if (GAP_SIZE < outgoing_nbytes)
1076 make_gap (outgoing_nbytes - GAP_SIZE);
1077 UNGCPRO;
1079 /* Copy the string text into the buffer, perhaps converting
1080 between single-byte and multibyte. */
1081 copy_text (SDATA (string) + pos_byte, GPT_ADDR, nbytes,
1082 STRING_MULTIBYTE (string),
1083 ! NILP (current_buffer->enable_multibyte_characters));
1085 #ifdef BYTE_COMBINING_DEBUG
1086 /* We have copied text into the gap, but we have not altered
1087 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1088 to these functions and get the same results as we would
1089 have got earlier on. Meanwhile, PT_ADDR does point to
1090 the text that has been stored by copy_text. */
1091 if (count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE)
1092 || count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE))
1093 abort ();
1094 #endif
1096 record_insert (PT, nchars);
1097 MODIFF++;
1098 CHARS_MODIFF = MODIFF;
1100 GAP_SIZE -= outgoing_nbytes;
1101 GPT += nchars;
1102 ZV += nchars;
1103 Z += nchars;
1104 GPT_BYTE += outgoing_nbytes;
1105 ZV_BYTE += outgoing_nbytes;
1106 Z_BYTE += outgoing_nbytes;
1107 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1109 if (GPT_BYTE < GPT)
1110 abort ();
1112 /* The insert may have been in the unchanged region, so check again. */
1113 if (Z - GPT < END_UNCHANGED)
1114 END_UNCHANGED = Z - GPT;
1116 adjust_overlays_for_insert (PT, nchars);
1117 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1118 PT_BYTE + outgoing_nbytes,
1119 before_markers);
1121 offset_intervals (current_buffer, PT, nchars);
1123 intervals = STRING_INTERVALS (string);
1124 /* Get the intervals for the part of the string we are inserting. */
1125 if (nbytes < SBYTES (string))
1126 intervals = copy_intervals (intervals, pos, nchars);
1128 /* Insert those intervals. */
1129 graft_intervals_into_buffer (intervals, PT, nchars,
1130 current_buffer, inherit);
1132 adjust_point (nchars, outgoing_nbytes);
1134 CHECK_MARKERS ();
1137 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1138 starting at GPT_ADDR. */
1140 void
1141 insert_from_gap (EMACS_INT nchars, EMACS_INT nbytes)
1143 if (NILP (current_buffer->enable_multibyte_characters))
1144 nchars = nbytes;
1146 record_insert (GPT, nchars);
1147 MODIFF++;
1149 GAP_SIZE -= nbytes;
1150 GPT += nchars;
1151 ZV += nchars;
1152 Z += nchars;
1153 GPT_BYTE += nbytes;
1154 ZV_BYTE += nbytes;
1155 Z_BYTE += nbytes;
1156 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1158 if (GPT_BYTE < GPT)
1159 abort ();
1161 adjust_overlays_for_insert (GPT - nchars, nchars);
1162 adjust_markers_for_insert (GPT - nchars, GPT_BYTE - nbytes,
1163 GPT, GPT_BYTE, 0);
1165 if (BUF_INTERVALS (current_buffer) != 0)
1167 offset_intervals (current_buffer, GPT - nchars, nchars);
1168 graft_intervals_into_buffer (NULL_INTERVAL, GPT - nchars, nchars,
1169 current_buffer, 0);
1172 if (GPT - nchars < PT)
1173 adjust_point (nchars, nbytes);
1175 CHECK_MARKERS ();
1178 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1179 current buffer. If the text in BUF has properties, they are absorbed
1180 into the current buffer.
1182 It does not work to use `insert' for this, because a malloc could happen
1183 and relocate BUF's text before the bcopy happens. */
1185 void
1186 insert_from_buffer (struct buffer *buf,
1187 EMACS_INT charpos, EMACS_INT nchars, int inherit)
1189 EMACS_INT opoint = PT;
1191 insert_from_buffer_1 (buf, charpos, nchars, inherit);
1192 signal_after_change (opoint, 0, PT - opoint);
1193 update_compositions (opoint, PT, CHECK_BORDER);
1196 static void
1197 insert_from_buffer_1 (struct buffer *buf,
1198 EMACS_INT from, EMACS_INT nchars, int inherit)
1200 register Lisp_Object temp;
1201 EMACS_INT chunk, chunk_expanded;
1202 EMACS_INT from_byte = buf_charpos_to_bytepos (buf, from);
1203 EMACS_INT to_byte = buf_charpos_to_bytepos (buf, from + nchars);
1204 EMACS_INT incoming_nbytes = to_byte - from_byte;
1205 EMACS_INT outgoing_nbytes = incoming_nbytes;
1206 INTERVAL intervals;
1208 /* Make OUTGOING_NBYTES describe the text
1209 as it will be inserted in this buffer. */
1211 if (NILP (current_buffer->enable_multibyte_characters))
1212 outgoing_nbytes = nchars;
1213 else if (NILP (buf->enable_multibyte_characters))
1215 EMACS_INT outgoing_before_gap = 0;
1216 EMACS_INT outgoing_after_gap = 0;
1218 if (from < BUF_GPT (buf))
1220 chunk = BUF_GPT_BYTE (buf) - from_byte;
1221 if (chunk > incoming_nbytes)
1222 chunk = incoming_nbytes;
1223 outgoing_before_gap
1224 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf, from_byte),
1225 chunk);
1227 else
1228 chunk = 0;
1230 if (chunk < incoming_nbytes)
1231 outgoing_after_gap
1232 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf,
1233 from_byte + chunk),
1234 incoming_nbytes - chunk);
1236 outgoing_nbytes = outgoing_before_gap + outgoing_after_gap;
1239 /* Make sure point-max won't overflow after this insertion. */
1240 XSETINT (temp, outgoing_nbytes + Z);
1241 if (outgoing_nbytes + Z != XINT (temp))
1242 error ("Maximum buffer size exceeded");
1244 /* Do this before moving and increasing the gap,
1245 because the before-change hooks might move the gap
1246 or make it smaller. */
1247 prepare_to_modify_buffer (PT, PT, NULL);
1249 if (PT != GPT)
1250 move_gap_both (PT, PT_BYTE);
1251 if (GAP_SIZE < outgoing_nbytes)
1252 make_gap (outgoing_nbytes - GAP_SIZE);
1254 if (from < BUF_GPT (buf))
1256 chunk = BUF_GPT_BYTE (buf) - from_byte;
1257 if (chunk > incoming_nbytes)
1258 chunk = incoming_nbytes;
1259 /* Record number of output bytes, so we know where
1260 to put the output from the second copy_text. */
1261 chunk_expanded
1262 = copy_text (BUF_BYTE_ADDRESS (buf, from_byte),
1263 GPT_ADDR, chunk,
1264 ! NILP (buf->enable_multibyte_characters),
1265 ! NILP (current_buffer->enable_multibyte_characters));
1267 else
1268 chunk_expanded = chunk = 0;
1270 if (chunk < incoming_nbytes)
1271 copy_text (BUF_BYTE_ADDRESS (buf, from_byte + chunk),
1272 GPT_ADDR + chunk_expanded, incoming_nbytes - chunk,
1273 ! NILP (buf->enable_multibyte_characters),
1274 ! NILP (current_buffer->enable_multibyte_characters));
1276 #ifdef BYTE_COMBINING_DEBUG
1277 /* We have copied text into the gap, but we have not altered
1278 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1279 to these functions and get the same results as we would
1280 have got earlier on. Meanwhile, GPT_ADDR does point to
1281 the text that has been stored by copy_text. */
1282 if (count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE)
1283 || count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE))
1284 abort ();
1285 #endif
1287 record_insert (PT, nchars);
1288 MODIFF++;
1289 CHARS_MODIFF = MODIFF;
1291 GAP_SIZE -= outgoing_nbytes;
1292 GPT += nchars;
1293 ZV += nchars;
1294 Z += nchars;
1295 GPT_BYTE += outgoing_nbytes;
1296 ZV_BYTE += outgoing_nbytes;
1297 Z_BYTE += outgoing_nbytes;
1298 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1300 if (GPT_BYTE < GPT)
1301 abort ();
1303 /* The insert may have been in the unchanged region, so check again. */
1304 if (Z - GPT < END_UNCHANGED)
1305 END_UNCHANGED = Z - GPT;
1307 adjust_overlays_for_insert (PT, nchars);
1308 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1309 PT_BYTE + outgoing_nbytes,
1312 if (BUF_INTERVALS (current_buffer) != 0)
1313 offset_intervals (current_buffer, PT, nchars);
1315 /* Get the intervals for the part of the string we are inserting. */
1316 intervals = BUF_INTERVALS (buf);
1317 if (nchars < BUF_Z (buf) - BUF_BEG (buf))
1319 if (buf == current_buffer && PT <= from)
1320 from += nchars;
1321 intervals = copy_intervals (intervals, from, nchars);
1324 /* Insert those intervals. */
1325 graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
1327 adjust_point (nchars, outgoing_nbytes);
1330 /* Record undo information and adjust markers and position keepers for
1331 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1332 chars (LEN_BYTE bytes) which resides in the gap just after
1333 GPT_ADDR.
1335 PREV_TEXT nil means the new text was just inserted. */
1337 void
1338 adjust_after_replace (EMACS_INT from, EMACS_INT from_byte,
1339 Lisp_Object prev_text, EMACS_INT len, EMACS_INT len_byte)
1341 EMACS_INT nchars_del = 0, nbytes_del = 0;
1343 #ifdef BYTE_COMBINING_DEBUG
1344 if (count_combining_before (GPT_ADDR, len_byte, from, from_byte)
1345 || count_combining_after (GPT_ADDR, len_byte, from, from_byte))
1346 abort ();
1347 #endif
1349 if (STRINGP (prev_text))
1351 nchars_del = SCHARS (prev_text);
1352 nbytes_del = SBYTES (prev_text);
1355 /* Update various buffer positions for the new text. */
1356 GAP_SIZE -= len_byte;
1357 ZV += len; Z+= len;
1358 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1359 GPT += len; GPT_BYTE += len_byte;
1360 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1362 if (nchars_del > 0)
1363 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1364 len, len_byte);
1365 else
1366 adjust_markers_for_insert (from, from_byte,
1367 from + len, from_byte + len_byte, 0);
1369 if (! EQ (current_buffer->undo_list, Qt))
1371 if (nchars_del > 0)
1372 record_delete (from, prev_text);
1373 record_insert (from, len);
1376 if (len > nchars_del)
1377 adjust_overlays_for_insert (from, len - nchars_del);
1378 else if (len < nchars_del)
1379 adjust_overlays_for_delete (from, nchars_del - len);
1380 if (BUF_INTERVALS (current_buffer) != 0)
1382 offset_intervals (current_buffer, from, len - nchars_del);
1385 if (from < PT)
1386 adjust_point (len - nchars_del, len_byte - nbytes_del);
1388 /* As byte combining will decrease Z, we must check this again. */
1389 if (Z - GPT < END_UNCHANGED)
1390 END_UNCHANGED = Z - GPT;
1392 CHECK_MARKERS ();
1394 if (len == 0)
1395 evaporate_overlays (from);
1396 MODIFF++;
1397 CHARS_MODIFF = MODIFF;
1400 /* Like adjust_after_replace, but doesn't require PREV_TEXT.
1401 This is for use when undo is not enabled in the current buffer. */
1403 void
1404 adjust_after_replace_noundo (EMACS_INT from, EMACS_INT from_byte,
1405 EMACS_INT nchars_del, EMACS_INT nbytes_del,
1406 EMACS_INT len, EMACS_INT len_byte)
1408 #ifdef BYTE_COMBINING_DEBUG
1409 if (count_combining_before (GPT_ADDR, len_byte, from, from_byte)
1410 || count_combining_after (GPT_ADDR, len_byte, from, from_byte))
1411 abort ();
1412 #endif
1414 /* Update various buffer positions for the new text. */
1415 GAP_SIZE -= len_byte;
1416 ZV += len; Z+= len;
1417 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1418 GPT += len; GPT_BYTE += len_byte;
1419 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1421 if (nchars_del > 0)
1422 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1423 len, len_byte);
1424 else
1425 adjust_markers_for_insert (from, from_byte,
1426 from + len, from_byte + len_byte, 0);
1428 if (len > nchars_del)
1429 adjust_overlays_for_insert (from, len - nchars_del);
1430 else if (len < nchars_del)
1431 adjust_overlays_for_delete (from, nchars_del - len);
1432 if (BUF_INTERVALS (current_buffer) != 0)
1434 offset_intervals (current_buffer, from, len - nchars_del);
1437 if (from < PT)
1438 adjust_point (len - nchars_del, len_byte - nbytes_del);
1440 /* As byte combining will decrease Z, we must check this again. */
1441 if (Z - GPT < END_UNCHANGED)
1442 END_UNCHANGED = Z - GPT;
1444 CHECK_MARKERS ();
1446 if (len == 0)
1447 evaporate_overlays (from);
1448 MODIFF++;
1449 CHARS_MODIFF = MODIFF;
1452 /* Record undo information, adjust markers and position keepers for an
1453 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1454 text already exists in the current buffer but character length (TO
1455 - FROM) may be incorrect, the correct length is NEWLEN. */
1457 void
1458 adjust_after_insert (EMACS_INT from, EMACS_INT from_byte,
1459 EMACS_INT to, EMACS_INT to_byte, EMACS_INT newlen)
1461 EMACS_INT len = to - from, len_byte = to_byte - from_byte;
1463 if (GPT != to)
1464 move_gap_both (to, to_byte);
1465 GAP_SIZE += len_byte;
1466 GPT -= len; GPT_BYTE -= len_byte;
1467 ZV -= len; ZV_BYTE -= len_byte;
1468 Z -= len; Z_BYTE -= len_byte;
1469 adjust_after_replace (from, from_byte, Qnil, newlen, len_byte);
1472 /* Replace the text from character positions FROM to TO with NEW,
1473 If PREPARE is nonzero, call prepare_to_modify_buffer.
1474 If INHERIT, the newly inserted text should inherit text properties
1475 from the surrounding non-deleted text. */
1477 /* Note that this does not yet handle markers quite right.
1478 Also it needs to record a single undo-entry that does a replacement
1479 rather than a separate delete and insert.
1480 That way, undo will also handle markers properly.
1482 But if MARKERS is 0, don't relocate markers. */
1484 void
1485 replace_range (EMACS_INT from, EMACS_INT to, Lisp_Object new,
1486 int prepare, int inherit, int markers)
1488 EMACS_INT inschars = SCHARS (new);
1489 EMACS_INT insbytes = SBYTES (new);
1490 EMACS_INT from_byte, to_byte;
1491 EMACS_INT nbytes_del, nchars_del;
1492 register Lisp_Object temp;
1493 struct gcpro gcpro1;
1494 INTERVAL intervals;
1495 EMACS_INT outgoing_insbytes = insbytes;
1496 Lisp_Object deletion;
1498 CHECK_MARKERS ();
1500 GCPRO1 (new);
1501 deletion = Qnil;
1503 if (prepare)
1505 EMACS_INT range_length = to - from;
1506 prepare_to_modify_buffer (from, to, &from);
1507 to = from + range_length;
1510 UNGCPRO;
1512 /* Make args be valid */
1513 if (from < BEGV)
1514 from = BEGV;
1515 if (to > ZV)
1516 to = ZV;
1518 from_byte = CHAR_TO_BYTE (from);
1519 to_byte = CHAR_TO_BYTE (to);
1521 nchars_del = to - from;
1522 nbytes_del = to_byte - from_byte;
1524 if (nbytes_del <= 0 && insbytes == 0)
1525 return;
1527 /* Make OUTGOING_INSBYTES describe the text
1528 as it will be inserted in this buffer. */
1530 if (NILP (current_buffer->enable_multibyte_characters))
1531 outgoing_insbytes = inschars;
1532 else if (! STRING_MULTIBYTE (new))
1533 outgoing_insbytes
1534 = count_size_as_multibyte (SDATA (new), insbytes);
1536 /* Make sure point-max won't overflow after this insertion. */
1537 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1538 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1539 error ("Maximum buffer size exceeded");
1541 GCPRO1 (new);
1543 /* Make sure the gap is somewhere in or next to what we are deleting. */
1544 if (from > GPT)
1545 gap_right (from, from_byte);
1546 if (to < GPT)
1547 gap_left (to, to_byte, 0);
1549 /* Even if we don't record for undo, we must keep the original text
1550 because we may have to recover it because of inappropriate byte
1551 combining. */
1552 if (! EQ (current_buffer->undo_list, Qt))
1553 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1555 GAP_SIZE += nbytes_del;
1556 ZV -= nchars_del;
1557 Z -= nchars_del;
1558 ZV_BYTE -= nbytes_del;
1559 Z_BYTE -= nbytes_del;
1560 GPT = from;
1561 GPT_BYTE = from_byte;
1562 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1564 if (GPT_BYTE < GPT)
1565 abort ();
1567 if (GPT - BEG < BEG_UNCHANGED)
1568 BEG_UNCHANGED = GPT - BEG;
1569 if (Z - GPT < END_UNCHANGED)
1570 END_UNCHANGED = Z - GPT;
1572 if (GAP_SIZE < insbytes)
1573 make_gap (insbytes - GAP_SIZE);
1575 /* Copy the string text into the buffer, perhaps converting
1576 between single-byte and multibyte. */
1577 copy_text (SDATA (new), GPT_ADDR, insbytes,
1578 STRING_MULTIBYTE (new),
1579 ! NILP (current_buffer->enable_multibyte_characters));
1581 #ifdef BYTE_COMBINING_DEBUG
1582 /* We have copied text into the gap, but we have not marked
1583 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1584 here, for both the previous text and the following text.
1585 Meanwhile, GPT_ADDR does point to
1586 the text that has been stored by copy_text. */
1587 if (count_combining_before (GPT_ADDR, outgoing_insbytes, from, from_byte)
1588 || count_combining_after (GPT_ADDR, outgoing_insbytes, from, from_byte))
1589 abort ();
1590 #endif
1592 if (! EQ (current_buffer->undo_list, Qt))
1594 /* Record the insertion first, so that when we undo,
1595 the deletion will be undone first. Thus, undo
1596 will insert before deleting, and thus will keep
1597 the markers before and after this text separate. */
1598 record_insert (from + SCHARS (deletion), inschars);
1599 record_delete (from, deletion);
1602 GAP_SIZE -= outgoing_insbytes;
1603 GPT += inschars;
1604 ZV += inschars;
1605 Z += inschars;
1606 GPT_BYTE += outgoing_insbytes;
1607 ZV_BYTE += outgoing_insbytes;
1608 Z_BYTE += outgoing_insbytes;
1609 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1611 if (GPT_BYTE < GPT)
1612 abort ();
1614 /* Adjust the overlay center as needed. This must be done after
1615 adjusting the markers that bound the overlays. */
1616 adjust_overlays_for_delete (from, nchars_del);
1617 adjust_overlays_for_insert (from, inschars);
1619 /* Adjust markers for the deletion and the insertion. */
1620 if (markers)
1621 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1622 inschars, outgoing_insbytes);
1624 offset_intervals (current_buffer, from, inschars - nchars_del);
1626 /* Get the intervals for the part of the string we are inserting--
1627 not including the combined-before bytes. */
1628 intervals = STRING_INTERVALS (new);
1629 /* Insert those intervals. */
1630 graft_intervals_into_buffer (intervals, from, inschars,
1631 current_buffer, inherit);
1633 /* Relocate point as if it were a marker. */
1634 if (from < PT)
1635 adjust_point ((from + inschars - (PT < to ? PT : to)),
1636 (from_byte + outgoing_insbytes
1637 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
1639 if (outgoing_insbytes == 0)
1640 evaporate_overlays (from);
1642 CHECK_MARKERS ();
1644 MODIFF++;
1645 CHARS_MODIFF = MODIFF;
1646 UNGCPRO;
1648 signal_after_change (from, nchars_del, GPT - from);
1649 update_compositions (from, GPT, CHECK_BORDER);
1652 /* Replace the text from character positions FROM to TO with
1653 the text in INS of length INSCHARS.
1654 Keep the text properties that applied to the old characters
1655 (extending them to all the new chars if there are more new chars).
1657 Note that this does not yet handle markers quite right.
1659 If MARKERS is nonzero, relocate markers.
1661 Unlike most functions at this level, never call
1662 prepare_to_modify_buffer and never call signal_after_change. */
1664 void
1665 replace_range_2 (EMACS_INT from, EMACS_INT from_byte,
1666 EMACS_INT to, EMACS_INT to_byte,
1667 char *ins, EMACS_INT inschars, EMACS_INT insbytes,
1668 int markers)
1670 EMACS_INT nbytes_del, nchars_del;
1671 Lisp_Object temp;
1673 CHECK_MARKERS ();
1675 nchars_del = to - from;
1676 nbytes_del = to_byte - from_byte;
1678 if (nbytes_del <= 0 && insbytes == 0)
1679 return;
1681 /* Make sure point-max won't overflow after this insertion. */
1682 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1683 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1684 error ("Maximum buffer size exceeded");
1686 /* Make sure the gap is somewhere in or next to what we are deleting. */
1687 if (from > GPT)
1688 gap_right (from, from_byte);
1689 if (to < GPT)
1690 gap_left (to, to_byte, 0);
1692 GAP_SIZE += nbytes_del;
1693 ZV -= nchars_del;
1694 Z -= nchars_del;
1695 ZV_BYTE -= nbytes_del;
1696 Z_BYTE -= nbytes_del;
1697 GPT = from;
1698 GPT_BYTE = from_byte;
1699 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1701 if (GPT_BYTE < GPT)
1702 abort ();
1704 if (GPT - BEG < BEG_UNCHANGED)
1705 BEG_UNCHANGED = GPT - BEG;
1706 if (Z - GPT < END_UNCHANGED)
1707 END_UNCHANGED = Z - GPT;
1709 if (GAP_SIZE < insbytes)
1710 make_gap (insbytes - GAP_SIZE);
1712 /* Copy the replacement text into the buffer. */
1713 bcopy (ins, GPT_ADDR, insbytes);
1715 #ifdef BYTE_COMBINING_DEBUG
1716 /* We have copied text into the gap, but we have not marked
1717 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1718 here, for both the previous text and the following text.
1719 Meanwhile, GPT_ADDR does point to
1720 the text that has been stored by copy_text. */
1721 if (count_combining_before (GPT_ADDR, insbytes, from, from_byte)
1722 || count_combining_after (GPT_ADDR, insbytes, from, from_byte))
1723 abort ();
1724 #endif
1726 GAP_SIZE -= insbytes;
1727 GPT += inschars;
1728 ZV += inschars;
1729 Z += inschars;
1730 GPT_BYTE += insbytes;
1731 ZV_BYTE += insbytes;
1732 Z_BYTE += insbytes;
1733 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1735 if (GPT_BYTE < GPT)
1736 abort ();
1738 /* Adjust the overlay center as needed. This must be done after
1739 adjusting the markers that bound the overlays. */
1740 if (nchars_del != inschars)
1742 adjust_overlays_for_insert (from, inschars);
1743 adjust_overlays_for_delete (from + inschars, nchars_del);
1746 /* Adjust markers for the deletion and the insertion. */
1747 if (markers
1748 && ! (nchars_del == 1 && inschars == 1 && nbytes_del == insbytes))
1749 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1750 inschars, insbytes);
1752 offset_intervals (current_buffer, from, inschars - nchars_del);
1754 /* Relocate point as if it were a marker. */
1755 if (from < PT && (nchars_del != inschars || nbytes_del != insbytes))
1757 if (PT < to)
1758 /* PT was within the deleted text. Move it to FROM. */
1759 adjust_point (from - PT, from_byte - PT_BYTE);
1760 else
1761 adjust_point (inschars - nchars_del, insbytes - nbytes_del);
1764 if (insbytes == 0)
1765 evaporate_overlays (from);
1767 CHECK_MARKERS ();
1769 MODIFF++;
1770 CHARS_MODIFF = MODIFF;
1773 /* Delete characters in current buffer
1774 from FROM up to (but not including) TO.
1775 If TO comes before FROM, we delete nothing. */
1777 void
1778 del_range (EMACS_INT from, EMACS_INT to)
1780 del_range_1 (from, to, 1, 0);
1783 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1784 RET_STRING says to return the deleted text. */
1786 Lisp_Object
1787 del_range_1 (EMACS_INT from, EMACS_INT to, int prepare, int ret_string)
1789 EMACS_INT from_byte, to_byte;
1790 Lisp_Object deletion;
1791 struct gcpro gcpro1;
1793 /* Make args be valid */
1794 if (from < BEGV)
1795 from = BEGV;
1796 if (to > ZV)
1797 to = ZV;
1799 if (to <= from)
1800 return Qnil;
1802 if (prepare)
1804 EMACS_INT range_length = to - from;
1805 prepare_to_modify_buffer (from, to, &from);
1806 to = min (ZV, from + range_length);
1809 from_byte = CHAR_TO_BYTE (from);
1810 to_byte = CHAR_TO_BYTE (to);
1812 deletion = del_range_2 (from, from_byte, to, to_byte, ret_string);
1813 GCPRO1(deletion);
1814 signal_after_change (from, to - from, 0);
1815 update_compositions (from, from, CHECK_HEAD);
1816 UNGCPRO;
1817 return deletion;
1820 /* Like del_range_1 but args are byte positions, not char positions. */
1822 void
1823 del_range_byte (EMACS_INT from_byte, EMACS_INT to_byte, int prepare)
1825 EMACS_INT from, to;
1827 /* Make args be valid */
1828 if (from_byte < BEGV_BYTE)
1829 from_byte = BEGV_BYTE;
1830 if (to_byte > ZV_BYTE)
1831 to_byte = ZV_BYTE;
1833 if (to_byte <= from_byte)
1834 return;
1836 from = BYTE_TO_CHAR (from_byte);
1837 to = BYTE_TO_CHAR (to_byte);
1839 if (prepare)
1841 EMACS_INT old_from = from, old_to = Z - to;
1842 EMACS_INT range_length = to - from;
1843 prepare_to_modify_buffer (from, to, &from);
1844 to = from + range_length;
1846 if (old_from != from)
1847 from_byte = CHAR_TO_BYTE (from);
1848 if (to > ZV)
1850 to = ZV;
1851 to_byte = ZV_BYTE;
1853 else if (old_to == Z - to)
1854 to_byte = CHAR_TO_BYTE (to);
1857 del_range_2 (from, from_byte, to, to_byte, 0);
1858 signal_after_change (from, to - from, 0);
1859 update_compositions (from, from, CHECK_HEAD);
1862 /* Like del_range_1, but positions are specified both as charpos
1863 and bytepos. */
1865 void
1866 del_range_both (EMACS_INT from, EMACS_INT from_byte,
1867 EMACS_INT to, EMACS_INT to_byte, int prepare)
1869 /* Make args be valid */
1870 if (from_byte < BEGV_BYTE)
1871 from_byte = BEGV_BYTE;
1872 if (to_byte > ZV_BYTE)
1873 to_byte = ZV_BYTE;
1875 if (to_byte <= from_byte)
1876 return;
1878 if (from < BEGV)
1879 from = BEGV;
1880 if (to > ZV)
1881 to = ZV;
1883 if (prepare)
1885 EMACS_INT old_from = from, old_to = Z - to;
1886 EMACS_INT range_length = to - from;
1887 prepare_to_modify_buffer (from, to, &from);
1888 to = from + range_length;
1890 if (old_from != from)
1891 from_byte = CHAR_TO_BYTE (from);
1892 if (to > ZV)
1894 to = ZV;
1895 to_byte = ZV_BYTE;
1897 else if (old_to == Z - to)
1898 to_byte = CHAR_TO_BYTE (to);
1901 del_range_2 (from, from_byte, to, to_byte, 0);
1902 signal_after_change (from, to - from, 0);
1903 update_compositions (from, from, CHECK_HEAD);
1906 /* Delete a range of text, specified both as character positions
1907 and byte positions. FROM and TO are character positions,
1908 while FROM_BYTE and TO_BYTE are byte positions.
1909 If RET_STRING is true, the deleted area is returned as a string. */
1911 Lisp_Object
1912 del_range_2 (EMACS_INT from, EMACS_INT from_byte,
1913 EMACS_INT to, EMACS_INT to_byte, int ret_string)
1915 register EMACS_INT nbytes_del, nchars_del;
1916 Lisp_Object deletion;
1918 CHECK_MARKERS ();
1920 nchars_del = to - from;
1921 nbytes_del = to_byte - from_byte;
1923 /* Make sure the gap is somewhere in or next to what we are deleting. */
1924 if (from > GPT)
1925 gap_right (from, from_byte);
1926 if (to < GPT)
1927 gap_left (to, to_byte, 0);
1929 #ifdef BYTE_COMBINING_DEBUG
1930 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte),
1931 Z_BYTE - to_byte, from, from_byte))
1932 abort ();
1933 #endif
1935 if (ret_string || ! EQ (current_buffer->undo_list, Qt))
1936 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1937 else
1938 deletion = Qnil;
1940 /* Relocate all markers pointing into the new, larger gap
1941 to point at the end of the text before the gap.
1942 Do this before recording the deletion,
1943 so that undo handles this after reinserting the text. */
1944 adjust_markers_for_delete (from, from_byte, to, to_byte);
1946 if (! EQ (current_buffer->undo_list, Qt))
1947 record_delete (from, deletion);
1948 MODIFF++;
1949 CHARS_MODIFF = MODIFF;
1951 /* Relocate point as if it were a marker. */
1952 if (from < PT)
1953 adjust_point (from - (PT < to ? PT : to),
1954 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte));
1956 offset_intervals (current_buffer, from, - nchars_del);
1958 /* Adjust the overlay center as needed. This must be done after
1959 adjusting the markers that bound the overlays. */
1960 adjust_overlays_for_delete (from, nchars_del);
1962 GAP_SIZE += nbytes_del;
1963 ZV_BYTE -= nbytes_del;
1964 Z_BYTE -= nbytes_del;
1965 ZV -= nchars_del;
1966 Z -= nchars_del;
1967 GPT = from;
1968 GPT_BYTE = from_byte;
1969 if (GAP_SIZE > 0 && !current_buffer->text->inhibit_shrinking)
1970 /* Put an anchor, unless called from decode_coding_object which
1971 needs to access the previous gap contents. */
1972 *(GPT_ADDR) = 0;
1974 if (GPT_BYTE < GPT)
1975 abort ();
1977 if (GPT - BEG < BEG_UNCHANGED)
1978 BEG_UNCHANGED = GPT - BEG;
1979 if (Z - GPT < END_UNCHANGED)
1980 END_UNCHANGED = Z - GPT;
1982 CHECK_MARKERS ();
1984 evaporate_overlays (from);
1986 return deletion;
1989 /* Call this if you're about to change the region of BUFFER from
1990 character positions START to END. This checks the read-only
1991 properties of the region, calls the necessary modification hooks,
1992 and warns the next redisplay that it should pay attention to that
1993 area.
1995 If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
1996 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1998 void
1999 modify_region (struct buffer *buffer, EMACS_INT start, EMACS_INT end,
2000 int preserve_chars_modiff)
2002 struct buffer *old_buffer = current_buffer;
2004 if (buffer != old_buffer)
2005 set_buffer_internal (buffer);
2007 prepare_to_modify_buffer (start, end, NULL);
2009 BUF_COMPUTE_UNCHANGED (buffer, start - 1, end);
2011 if (MODIFF <= SAVE_MODIFF)
2012 record_first_change ();
2013 MODIFF++;
2014 if (! preserve_chars_modiff)
2015 CHARS_MODIFF = MODIFF;
2017 buffer->point_before_scroll = Qnil;
2019 if (buffer != old_buffer)
2020 set_buffer_internal (old_buffer);
2023 /* Check that it is okay to modify the buffer between START and END,
2024 which are char positions.
2026 Run the before-change-function, if any. If intervals are in use,
2027 verify that the text to be modified is not read-only, and call
2028 any modification properties the text may have.
2030 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2031 by holding its value temporarily in a marker. */
2033 void
2034 prepare_to_modify_buffer (EMACS_INT start, EMACS_INT end,
2035 EMACS_INT *preserve_ptr)
2037 struct buffer *base_buffer;
2039 if (!NILP (current_buffer->read_only))
2040 Fbarf_if_buffer_read_only ();
2042 /* Let redisplay consider other windows than selected_window
2043 if modifying another buffer. */
2044 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
2045 ++windows_or_buffers_changed;
2047 if (BUF_INTERVALS (current_buffer) != 0)
2049 if (preserve_ptr)
2051 Lisp_Object preserve_marker;
2052 struct gcpro gcpro1;
2053 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
2054 GCPRO1 (preserve_marker);
2055 verify_interval_modification (current_buffer, start, end);
2056 *preserve_ptr = marker_position (preserve_marker);
2057 unchain_marker (XMARKER (preserve_marker));
2058 UNGCPRO;
2060 else
2061 verify_interval_modification (current_buffer, start, end);
2064 /* For indirect buffers, use the base buffer to check clashes. */
2065 if (current_buffer->base_buffer != 0)
2066 base_buffer = current_buffer->base_buffer;
2067 else
2068 base_buffer = current_buffer;
2070 #ifdef CLASH_DETECTION
2071 if (!NILP (base_buffer->file_truename)
2072 /* Make binding buffer-file-name to nil effective. */
2073 && !NILP (base_buffer->filename)
2074 && SAVE_MODIFF >= MODIFF)
2075 lock_file (base_buffer->file_truename);
2076 #else
2077 /* At least warn if this file has changed on disk since it was visited. */
2078 if (!NILP (base_buffer->filename)
2079 && SAVE_MODIFF >= MODIFF
2080 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2081 && !NILP (Ffile_exists_p (base_buffer->filename)))
2082 call1 (intern ("ask-user-about-supersession-threat"),
2083 base_buffer->filename);
2084 #endif /* not CLASH_DETECTION */
2086 signal_before_change (start, end, preserve_ptr);
2088 if (current_buffer->newline_cache)
2089 invalidate_region_cache (current_buffer,
2090 current_buffer->newline_cache,
2091 start - BEG, Z - end);
2092 if (current_buffer->width_run_cache)
2093 invalidate_region_cache (current_buffer,
2094 current_buffer->width_run_cache,
2095 start - BEG, Z - end);
2097 Vdeactivate_mark = Qt;
2100 /* These macros work with an argument named `preserve_ptr'
2101 and a local variable named `preserve_marker'. */
2103 #define PRESERVE_VALUE \
2104 if (preserve_ptr && NILP (preserve_marker)) \
2105 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2107 #define RESTORE_VALUE \
2108 if (! NILP (preserve_marker)) \
2110 *preserve_ptr = marker_position (preserve_marker); \
2111 unchain_marker (XMARKER (preserve_marker)); \
2114 #define PRESERVE_START_END \
2115 if (NILP (start_marker)) \
2116 start_marker = Fcopy_marker (start, Qnil); \
2117 if (NILP (end_marker)) \
2118 end_marker = Fcopy_marker (end, Qnil);
2120 #define FETCH_START \
2121 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2123 #define FETCH_END \
2124 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2126 /* Set a variable to nil if an error occurred.
2127 Don't change the variable if there was no error.
2128 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
2129 VARIABLE is the variable to maybe set to nil.
2130 NO-ERROR-FLAG is nil if there was an error,
2131 anything else meaning no error (so this function does nothing). */
2132 Lisp_Object
2133 reset_var_on_error (val)
2134 Lisp_Object val;
2136 if (NILP (XCDR (val)))
2137 Fset (XCAR (val), Qnil);
2138 return Qnil;
2141 /* Signal a change to the buffer immediately before it happens.
2142 START_INT and END_INT are the bounds of the text to be changed.
2144 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2145 by holding its value temporarily in a marker. */
2147 void
2148 signal_before_change (EMACS_INT start_int, EMACS_INT end_int,
2149 EMACS_INT *preserve_ptr)
2151 Lisp_Object start, end;
2152 Lisp_Object start_marker, end_marker;
2153 Lisp_Object preserve_marker;
2154 struct gcpro gcpro1, gcpro2, gcpro3;
2155 int count = SPECPDL_INDEX ();
2157 if (inhibit_modification_hooks)
2158 return;
2160 start = make_number (start_int);
2161 end = make_number (end_int);
2162 preserve_marker = Qnil;
2163 start_marker = Qnil;
2164 end_marker = Qnil;
2165 GCPRO3 (preserve_marker, start_marker, end_marker);
2167 specbind (Qinhibit_modification_hooks, Qt);
2169 /* If buffer is unmodified, run a special hook for that case. */
2170 if (SAVE_MODIFF >= MODIFF
2171 && !NILP (Vfirst_change_hook)
2172 && !NILP (Vrun_hooks))
2174 PRESERVE_VALUE;
2175 PRESERVE_START_END;
2176 call1 (Vrun_hooks, Qfirst_change_hook);
2179 /* Now run the before-change-functions if any. */
2180 if (!NILP (Vbefore_change_functions))
2182 Lisp_Object args[3];
2183 Lisp_Object rvoe_arg = Fcons (Qbefore_change_functions, Qnil);
2185 PRESERVE_VALUE;
2186 PRESERVE_START_END;
2188 /* Mark before-change-functions to be reset to nil in case of error. */
2189 record_unwind_protect (reset_var_on_error, rvoe_arg);
2191 /* Actually run the hook functions. */
2192 args[0] = Qbefore_change_functions;
2193 args[1] = FETCH_START;
2194 args[2] = FETCH_END;
2195 Frun_hook_with_args (3, args);
2197 /* There was no error: unarm the reset_on_error. */
2198 XSETCDR (rvoe_arg, Qt);
2201 if (current_buffer->overlays_before || current_buffer->overlays_after)
2203 PRESERVE_VALUE;
2204 report_overlay_modification (FETCH_START, FETCH_END, 0,
2205 FETCH_START, FETCH_END, Qnil);
2208 if (! NILP (start_marker))
2209 free_marker (start_marker);
2210 if (! NILP (end_marker))
2211 free_marker (end_marker);
2212 RESTORE_VALUE;
2213 UNGCPRO;
2215 unbind_to (count, Qnil);
2218 /* Signal a change immediately after it happens.
2219 CHARPOS is the character position of the start of the changed text.
2220 LENDEL is the number of characters of the text before the change.
2221 (Not the whole buffer; just the part that was changed.)
2222 LENINS is the number of characters in that part of the text
2223 after the change. */
2225 void
2226 signal_after_change (EMACS_INT charpos, EMACS_INT lendel, EMACS_INT lenins)
2228 int count = SPECPDL_INDEX ();
2229 if (inhibit_modification_hooks)
2230 return;
2232 /* If we are deferring calls to the after-change functions
2233 and there are no before-change functions,
2234 just record the args that we were going to use. */
2235 if (! NILP (Vcombine_after_change_calls)
2236 && NILP (Vbefore_change_functions)
2237 && !current_buffer->overlays_before
2238 && !current_buffer->overlays_after)
2240 Lisp_Object elt;
2242 if (!NILP (combine_after_change_list)
2243 && current_buffer != XBUFFER (combine_after_change_buffer))
2244 Fcombine_after_change_execute ();
2246 elt = Fcons (make_number (charpos - BEG),
2247 Fcons (make_number (Z - (charpos - lendel + lenins)),
2248 Fcons (make_number (lenins - lendel), Qnil)));
2249 combine_after_change_list
2250 = Fcons (elt, combine_after_change_list);
2251 combine_after_change_buffer = Fcurrent_buffer ();
2253 return;
2256 if (!NILP (combine_after_change_list))
2257 Fcombine_after_change_execute ();
2259 specbind (Qinhibit_modification_hooks, Qt);
2261 if (!NILP (Vafter_change_functions))
2263 Lisp_Object args[4];
2264 Lisp_Object rvoe_arg = Fcons (Qafter_change_functions, Qnil);
2266 /* Mark after-change-functions to be reset to nil in case of error. */
2267 record_unwind_protect (reset_var_on_error, rvoe_arg);
2269 /* Actually run the hook functions. */
2270 args[0] = Qafter_change_functions;
2271 XSETFASTINT (args[1], charpos);
2272 XSETFASTINT (args[2], charpos + lenins);
2273 XSETFASTINT (args[3], lendel);
2274 Frun_hook_with_args (4, args);
2276 /* There was no error: unarm the reset_on_error. */
2277 XSETCDR (rvoe_arg, Qt);
2280 if (current_buffer->overlays_before || current_buffer->overlays_after)
2281 report_overlay_modification (make_number (charpos),
2282 make_number (charpos + lenins),
2284 make_number (charpos),
2285 make_number (charpos + lenins),
2286 make_number (lendel));
2288 /* After an insertion, call the text properties
2289 insert-behind-hooks or insert-in-front-hooks. */
2290 if (lendel == 0)
2291 report_interval_modification (make_number (charpos),
2292 make_number (charpos + lenins));
2294 unbind_to (count, Qnil);
2297 Lisp_Object
2298 Fcombine_after_change_execute_1 (val)
2299 Lisp_Object val;
2301 Vcombine_after_change_calls = val;
2302 return val;
2305 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
2306 Scombine_after_change_execute, 0, 0, 0,
2307 doc: /* This function is for use internally in `combine-after-change-calls'. */)
2310 int count = SPECPDL_INDEX ();
2311 EMACS_INT beg, end, change;
2312 EMACS_INT begpos, endpos;
2313 Lisp_Object tail;
2315 if (NILP (combine_after_change_list))
2316 return Qnil;
2318 /* It is rare for combine_after_change_buffer to be invalid, but
2319 possible. It can happen when combine-after-change-calls is
2320 non-nil, and insertion calls a file handler (e.g. through
2321 lock_file) which scribbles into a temp file -- cyd */
2322 if (!BUFFERP (combine_after_change_buffer)
2323 || NILP (XBUFFER (combine_after_change_buffer)->name))
2325 combine_after_change_list = Qnil;
2326 return Qnil;
2329 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
2331 Fset_buffer (combine_after_change_buffer);
2333 /* # chars unchanged at beginning of buffer. */
2334 beg = Z - BEG;
2335 /* # chars unchanged at end of buffer. */
2336 end = beg;
2337 /* Total amount of insertion (negative for deletion). */
2338 change = 0;
2340 /* Scan the various individual changes,
2341 accumulating the range info in BEG, END and CHANGE. */
2342 for (tail = combine_after_change_list; CONSP (tail);
2343 tail = XCDR (tail))
2345 Lisp_Object elt;
2346 EMACS_INT thisbeg, thisend, thischange;
2348 /* Extract the info from the next element. */
2349 elt = XCAR (tail);
2350 if (! CONSP (elt))
2351 continue;
2352 thisbeg = XINT (XCAR (elt));
2354 elt = XCDR (elt);
2355 if (! CONSP (elt))
2356 continue;
2357 thisend = XINT (XCAR (elt));
2359 elt = XCDR (elt);
2360 if (! CONSP (elt))
2361 continue;
2362 thischange = XINT (XCAR (elt));
2364 /* Merge this range into the accumulated range. */
2365 change += thischange;
2366 if (thisbeg < beg)
2367 beg = thisbeg;
2368 if (thisend < end)
2369 end = thisend;
2372 /* Get the current start and end positions of the range
2373 that was changed. */
2374 begpos = BEG + beg;
2375 endpos = Z - end;
2377 /* We are about to handle these, so discard them. */
2378 combine_after_change_list = Qnil;
2380 /* Now run the after-change functions for real.
2381 Turn off the flag that defers them. */
2382 record_unwind_protect (Fcombine_after_change_execute_1,
2383 Vcombine_after_change_calls);
2384 signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
2385 update_compositions (begpos, endpos, CHECK_ALL);
2387 return unbind_to (count, Qnil);
2390 void
2391 syms_of_insdel ()
2393 staticpro (&combine_after_change_list);
2394 staticpro (&combine_after_change_buffer);
2395 combine_after_change_list = Qnil;
2396 combine_after_change_buffer = Qnil;
2398 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag,
2399 doc: /* Non-nil means enable debugging checks for invalid marker positions. */);
2400 check_markers_debug_flag = 0;
2401 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
2402 doc: /* Used internally by the `combine-after-change-calls' macro. */);
2403 Vcombine_after_change_calls = Qnil;
2405 DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks,
2406 doc: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2407 This affects `before-change-functions' and `after-change-functions',
2408 as well as hooks attached to text properties and overlays. */);
2409 inhibit_modification_hooks = 0;
2410 Qinhibit_modification_hooks = intern_c_string ("inhibit-modification-hooks");
2411 staticpro (&Qinhibit_modification_hooks);
2413 defsubr (&Scombine_after_change_execute);
2416 /* arch-tag: 9b34b886-47d7-465e-a234-299af411b23d
2417 (do not change this comment) */