* dbusbind.c (syms_of_dbusbind): Unset $DBUS_FATAL_WARNINGS.
[emacs.git] / src / insdel.c
blobededd597b0dc183dd9b0310f0843c7953ffae7f1
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
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 BUF_PT (current_buffer) += nchars;
463 BUF_PT_BYTE (current_buffer) += nbytes;
465 /* In a single-byte buffer, the two positions must be equal. */
466 eassert (PT_BYTE >= PT && PT_BYTE - PT <= ZV_BYTE - ZV);
469 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
470 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
471 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
472 an insertion. */
474 static void
475 adjust_markers_for_replace (EMACS_INT from, EMACS_INT from_byte,
476 EMACS_INT old_chars, EMACS_INT old_bytes,
477 EMACS_INT new_chars, EMACS_INT new_bytes)
479 register struct Lisp_Marker *m;
480 EMACS_INT prev_to_byte = from_byte + old_bytes;
481 EMACS_INT diff_chars = new_chars - old_chars;
482 EMACS_INT diff_bytes = new_bytes - old_bytes;
484 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
486 if (m->bytepos >= prev_to_byte)
488 m->charpos += diff_chars;
489 m->bytepos += diff_bytes;
491 else if (m->bytepos > from_byte)
493 m->charpos = from;
494 m->bytepos = from_byte;
498 CHECK_MARKERS ();
502 /* Make the gap NBYTES_ADDED bytes longer. */
504 void
505 make_gap_larger (EMACS_INT nbytes_added)
507 Lisp_Object tem;
508 EMACS_INT real_gap_loc;
509 EMACS_INT real_gap_loc_byte;
510 EMACS_INT old_gap_size;
512 /* If we have to get more space, get enough to last a while. */
513 nbytes_added += 2000;
515 { EMACS_INT total_size = Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added;
516 if (total_size < 0
517 /* Don't allow a buffer size that won't fit in a Lisp integer. */
518 || total_size != XINT (make_number (total_size))
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 still use `int'. */
522 || total_size != (EMACS_INT) (int) total_size)
523 error ("Buffer exceeds maximum size");
526 enlarge_buffer_text (current_buffer, nbytes_added);
528 /* Prevent quitting in move_gap. */
529 tem = Vinhibit_quit;
530 Vinhibit_quit = Qt;
532 real_gap_loc = GPT;
533 real_gap_loc_byte = GPT_BYTE;
534 old_gap_size = GAP_SIZE;
536 /* Call the newly allocated space a gap at the end of the whole space. */
537 GPT = Z + GAP_SIZE;
538 GPT_BYTE = Z_BYTE + GAP_SIZE;
539 GAP_SIZE = nbytes_added;
541 /* Move the new gap down to be consecutive with the end of the old one.
542 This adjusts the markers properly too. */
543 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
545 /* Now combine the two into one large gap. */
546 GAP_SIZE += old_gap_size;
547 GPT = real_gap_loc;
548 GPT_BYTE = real_gap_loc_byte;
550 /* Put an anchor. */
551 *(Z_ADDR) = 0;
553 Vinhibit_quit = tem;
557 /* Make the gap NBYTES_REMOVED bytes shorter. */
559 void
560 make_gap_smaller (EMACS_INT nbytes_removed)
562 Lisp_Object tem;
563 EMACS_INT real_gap_loc;
564 EMACS_INT real_gap_loc_byte;
565 EMACS_INT real_Z;
566 EMACS_INT real_Z_byte;
567 EMACS_INT real_beg_unchanged;
568 EMACS_INT new_gap_size;
570 /* Make sure the gap is at least 20 bytes. */
571 if (GAP_SIZE - nbytes_removed < 20)
572 nbytes_removed = GAP_SIZE - 20;
574 /* Prevent quitting in move_gap. */
575 tem = Vinhibit_quit;
576 Vinhibit_quit = Qt;
578 real_gap_loc = GPT;
579 real_gap_loc_byte = GPT_BYTE;
580 new_gap_size = GAP_SIZE - nbytes_removed;
581 real_Z = Z;
582 real_Z_byte = Z_BYTE;
583 real_beg_unchanged = BEG_UNCHANGED;
585 /* Pretend that the last unwanted part of the gap is the entire gap,
586 and that the first desired part of the gap is part of the buffer
587 text. */
588 bzero (GPT_ADDR, new_gap_size);
589 GPT += new_gap_size;
590 GPT_BYTE += new_gap_size;
591 Z += new_gap_size;
592 Z_BYTE += new_gap_size;
593 GAP_SIZE = nbytes_removed;
595 /* Move the unwanted pretend gap to the end of the buffer. This
596 adjusts the markers properly too. */
597 gap_right (Z, Z_BYTE);
599 enlarge_buffer_text (current_buffer, -nbytes_removed);
601 /* Now restore the desired gap. */
602 GAP_SIZE = new_gap_size;
603 GPT = real_gap_loc;
604 GPT_BYTE = real_gap_loc_byte;
605 Z = real_Z;
606 Z_BYTE = real_Z_byte;
607 BEG_UNCHANGED = real_beg_unchanged;
609 /* Put an anchor. */
610 *(Z_ADDR) = 0;
612 Vinhibit_quit = tem;
615 void
616 make_gap (EMACS_INT nbytes_added)
618 if (nbytes_added >= 0)
619 make_gap_larger (nbytes_added);
620 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
621 else
622 make_gap_smaller (-nbytes_added);
623 #endif
626 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
627 FROM_MULTIBYTE says whether the incoming text is multibyte.
628 TO_MULTIBYTE says whether to store the text as multibyte.
629 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
631 Return the number of bytes stored at TO_ADDR. */
633 EMACS_INT
634 copy_text (const unsigned char *from_addr, unsigned char *to_addr,
635 EMACS_INT nbytes, int from_multibyte, int to_multibyte)
637 if (from_multibyte == to_multibyte)
639 bcopy (from_addr, to_addr, nbytes);
640 return nbytes;
642 else if (from_multibyte)
644 EMACS_INT nchars = 0;
645 EMACS_INT bytes_left = nbytes;
646 Lisp_Object tbl = Qnil;
648 while (bytes_left > 0)
650 int thislen, c;
651 c = STRING_CHAR_AND_LENGTH (from_addr, thislen);
652 if (! ASCII_CHAR_P (c))
653 c &= 0xFF;
654 *to_addr++ = c;
655 from_addr += thislen;
656 bytes_left -= thislen;
657 nchars++;
659 return nchars;
661 else
663 unsigned char *initial_to_addr = to_addr;
665 /* Convert single-byte to multibyte. */
666 while (nbytes > 0)
668 int c = *from_addr++;
670 if (!ASCII_CHAR_P (c))
672 c = BYTE8_TO_CHAR (c);
673 to_addr += CHAR_STRING (c, to_addr);
674 nbytes--;
676 else
677 /* Special case for speed. */
678 *to_addr++ = c, nbytes--;
680 return to_addr - initial_to_addr;
684 /* Return the number of bytes it would take
685 to convert some single-byte text to multibyte.
686 The single-byte text consists of NBYTES bytes at PTR. */
688 EMACS_INT
689 count_size_as_multibyte (const unsigned char *ptr, EMACS_INT nbytes)
691 EMACS_INT i;
692 EMACS_INT outgoing_nbytes = 0;
694 for (i = 0; i < nbytes; i++)
696 unsigned int c = *ptr++;
698 if (ASCII_CHAR_P (c))
699 outgoing_nbytes++;
700 else
702 c = BYTE8_TO_CHAR (c);
703 outgoing_nbytes += CHAR_BYTES (c);
707 return outgoing_nbytes;
710 /* Insert a string of specified length before point.
711 This function judges multibyteness based on
712 enable_multibyte_characters in the current buffer;
713 it never converts between single-byte and multibyte.
715 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
716 prepare_to_modify_buffer could relocate the text. */
718 void
719 insert (const unsigned char *string, EMACS_INT nbytes)
721 if (nbytes > 0)
723 EMACS_INT len = chars_in_text (string, nbytes), opoint;
724 insert_1_both (string, len, nbytes, 0, 1, 0);
725 opoint = PT - len;
726 signal_after_change (opoint, 0, len);
727 update_compositions (opoint, PT, CHECK_BORDER);
731 /* Likewise, but inherit text properties from neighboring characters. */
733 void
734 insert_and_inherit (const unsigned char *string, EMACS_INT nbytes)
736 if (nbytes > 0)
738 EMACS_INT len = chars_in_text (string, nbytes), opoint;
739 insert_1_both (string, len, nbytes, 1, 1, 0);
740 opoint = PT - len;
741 signal_after_change (opoint, 0, len);
742 update_compositions (opoint, PT, CHECK_BORDER);
746 /* Insert the character C before point. Do not inherit text properties. */
748 void
749 insert_char (int c)
751 unsigned char str[MAX_MULTIBYTE_LENGTH];
752 int len;
754 if (! NILP (current_buffer->enable_multibyte_characters))
755 len = CHAR_STRING (c, str);
756 else
758 len = 1;
759 str[0] = c;
762 insert (str, len);
765 /* Insert the null-terminated string S before point. */
767 void
768 insert_string (const char *s)
770 insert (s, strlen (s));
773 /* Like `insert' except that all markers pointing at the place where
774 the insertion happens are adjusted to point after it.
775 Don't use this function to insert part of a Lisp string,
776 since gc could happen and relocate it. */
778 void
779 insert_before_markers (const unsigned char *string, EMACS_INT nbytes)
781 if (nbytes > 0)
783 EMACS_INT len = chars_in_text (string, nbytes), opoint;
784 insert_1_both (string, len, nbytes, 0, 1, 1);
785 opoint = PT - len;
786 signal_after_change (opoint, 0, len);
787 update_compositions (opoint, PT, CHECK_BORDER);
791 /* Likewise, but inherit text properties from neighboring characters. */
793 void
794 insert_before_markers_and_inherit (const unsigned char *string,
795 EMACS_INT nbytes)
797 if (nbytes > 0)
799 EMACS_INT len = chars_in_text (string, nbytes), opoint;
800 insert_1_both (string, len, nbytes, 1, 1, 1);
801 opoint = PT - len;
802 signal_after_change (opoint, 0, len);
803 update_compositions (opoint, PT, CHECK_BORDER);
807 /* Subroutine used by the insert functions above. */
809 void
810 insert_1 (const unsigned char *string, EMACS_INT nbytes,
811 int inherit, int prepare, int before_markers)
813 insert_1_both (string, chars_in_text (string, nbytes), nbytes,
814 inherit, prepare, before_markers);
818 #ifdef BYTE_COMBINING_DEBUG
820 /* See if the bytes before POS/POS_BYTE combine with bytes
821 at the start of STRING to form a single character.
822 If so, return the number of bytes at the start of STRING
823 which combine in this way. Otherwise, return 0. */
826 count_combining_before (const unsigned char *string, EMACS_INT length,
827 EMACS_INT pos, EMACS_INT pos_byte)
829 int len, combining_bytes;
830 const unsigned char *p;
832 if (NILP (current_buffer->enable_multibyte_characters))
833 return 0;
835 /* At first, we can exclude the following cases:
836 (1) STRING[0] can't be a following byte of multibyte sequence.
837 (2) POS is the start of the current buffer.
838 (3) A character before POS is not a multibyte character. */
839 if (length == 0 || CHAR_HEAD_P (*string)) /* case (1) */
840 return 0;
841 if (pos_byte == BEG_BYTE) /* case (2) */
842 return 0;
843 len = 1;
844 p = BYTE_POS_ADDR (pos_byte - 1);
845 while (! CHAR_HEAD_P (*p)) p--, len++;
846 if (! BASE_LEADING_CODE_P (*p)) /* case (3) */
847 return 0;
849 combining_bytes = BYTES_BY_CHAR_HEAD (*p) - len;
850 if (combining_bytes <= 0)
851 /* The character preceding POS is, complete and no room for
852 combining bytes (combining_bytes == 0), or an independent 8-bit
853 character (combining_bytes < 0). */
854 return 0;
856 /* We have a combination situation. Count the bytes at STRING that
857 may combine. */
858 p = string + 1;
859 while (!CHAR_HEAD_P (*p) && p < string + length)
860 p++;
862 return (combining_bytes < p - string ? combining_bytes : p - string);
865 /* See if the bytes after POS/POS_BYTE combine with bytes
866 at the end of STRING to form a single character.
867 If so, return the number of bytes after POS/POS_BYTE
868 which combine in this way. Otherwise, return 0. */
871 count_combining_after (const unsigned char *string,
872 EMACS_INT length, EMACS_INT pos, EMACS_INT pos_byte)
874 EMACS_INT opos_byte = pos_byte;
875 EMACS_INT i;
876 EMACS_INT bytes;
877 unsigned char *bufp;
879 if (NILP (current_buffer->enable_multibyte_characters))
880 return 0;
882 /* At first, we can exclude the following cases:
883 (1) The last byte of STRING is an ASCII.
884 (2) POS is the last of the current buffer.
885 (3) A character at POS can't be a following byte of multibyte
886 character. */
887 if (length > 0 && ASCII_BYTE_P (string[length - 1])) /* case (1) */
888 return 0;
889 if (pos_byte == Z_BYTE) /* case (2) */
890 return 0;
891 bufp = BYTE_POS_ADDR (pos_byte);
892 if (CHAR_HEAD_P (*bufp)) /* case (3) */
893 return 0;
895 i = length - 1;
896 while (i >= 0 && ! CHAR_HEAD_P (string[i]))
898 i--;
900 if (i < 0)
902 /* All characters in STRING are not character head. We must
903 check also preceding bytes at POS. We are sure that the gap
904 is at POS. */
905 unsigned char *p = BEG_ADDR;
906 i = pos_byte - 2;
907 while (i >= 0 && ! CHAR_HEAD_P (p[i]))
908 i--;
909 if (i < 0 || !BASE_LEADING_CODE_P (p[i]))
910 return 0;
912 bytes = BYTES_BY_CHAR_HEAD (p[i]);
913 return (bytes <= pos_byte - 1 - i + length
915 : bytes - (pos_byte - 1 - i + length));
917 if (!BASE_LEADING_CODE_P (string[i]))
918 return 0;
920 bytes = BYTES_BY_CHAR_HEAD (string[i]) - (length - i);
921 bufp++, pos_byte++;
922 while (!CHAR_HEAD_P (*bufp)) bufp++, pos_byte++;
924 return (bytes <= pos_byte - opos_byte ? bytes : pos_byte - opos_byte);
927 #endif
930 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
931 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
932 are the same as in insert_1. */
934 void
935 insert_1_both (const unsigned char *string,
936 EMACS_INT nchars, EMACS_INT nbytes,
937 int inherit, int prepare, int before_markers)
939 if (nchars == 0)
940 return;
942 if (NILP (current_buffer->enable_multibyte_characters))
943 nchars = nbytes;
945 if (prepare)
946 /* Do this before moving and increasing the gap,
947 because the before-change hooks might move the gap
948 or make it smaller. */
949 prepare_to_modify_buffer (PT, PT, NULL);
951 if (PT != GPT)
952 move_gap_both (PT, PT_BYTE);
953 if (GAP_SIZE < nbytes)
954 make_gap (nbytes - GAP_SIZE);
956 #ifdef BYTE_COMBINING_DEBUG
957 if (count_combining_before (string, nbytes, PT, PT_BYTE)
958 || count_combining_after (string, nbytes, PT, PT_BYTE))
959 abort ();
960 #endif
962 /* Record deletion of the surrounding text that combines with
963 the insertion. This, together with recording the insertion,
964 will add up to the right stuff in the undo list. */
965 record_insert (PT, nchars);
966 MODIFF++;
967 CHARS_MODIFF = MODIFF;
969 bcopy (string, GPT_ADDR, nbytes);
971 GAP_SIZE -= nbytes;
972 GPT += nchars;
973 ZV += nchars;
974 Z += nchars;
975 GPT_BYTE += nbytes;
976 ZV_BYTE += nbytes;
977 Z_BYTE += nbytes;
978 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
980 if (GPT_BYTE < GPT)
981 abort ();
983 /* The insert may have been in the unchanged region, so check again. */
984 if (Z - GPT < END_UNCHANGED)
985 END_UNCHANGED = Z - GPT;
987 adjust_overlays_for_insert (PT, nchars);
988 adjust_markers_for_insert (PT, PT_BYTE,
989 PT + nchars, PT_BYTE + nbytes,
990 before_markers);
992 if (BUF_INTERVALS (current_buffer) != 0)
993 offset_intervals (current_buffer, PT, nchars);
995 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
996 set_text_properties (make_number (PT), make_number (PT + nchars),
997 Qnil, Qnil, Qnil);
999 adjust_point (nchars, nbytes);
1001 CHECK_MARKERS ();
1004 /* Insert the part of the text of STRING, a Lisp object assumed to be
1005 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1006 starting at position POS / POS_BYTE. If the text of STRING has properties,
1007 copy them into the buffer.
1009 It does not work to use `insert' for this, because a GC could happen
1010 before we bcopy the stuff into the buffer, and relocate the string
1011 without insert noticing. */
1013 void
1014 insert_from_string (Lisp_Object string, EMACS_INT pos, EMACS_INT pos_byte,
1015 EMACS_INT length, EMACS_INT length_byte, int inherit)
1017 EMACS_INT opoint = PT;
1019 if (SCHARS (string) == 0)
1020 return;
1022 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1023 inherit, 0);
1024 signal_after_change (opoint, 0, PT - opoint);
1025 update_compositions (opoint, PT, CHECK_BORDER);
1028 /* Like `insert_from_string' except that all markers pointing
1029 at the place where the insertion happens are adjusted to point after it. */
1031 void
1032 insert_from_string_before_markers (Lisp_Object string,
1033 EMACS_INT pos, EMACS_INT pos_byte,
1034 EMACS_INT length, EMACS_INT length_byte,
1035 int inherit)
1037 EMACS_INT opoint = PT;
1039 if (SCHARS (string) == 0)
1040 return;
1042 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1043 inherit, 1);
1044 signal_after_change (opoint, 0, PT - opoint);
1045 update_compositions (opoint, PT, CHECK_BORDER);
1048 /* Subroutine of the insertion functions above. */
1050 static void
1051 insert_from_string_1 (Lisp_Object string, EMACS_INT pos, EMACS_INT pos_byte,
1052 EMACS_INT nchars, EMACS_INT nbytes,
1053 int inherit, int before_markers)
1055 struct gcpro gcpro1;
1056 EMACS_INT outgoing_nbytes = nbytes;
1057 INTERVAL intervals;
1059 /* Make OUTGOING_NBYTES describe the text
1060 as it will be inserted in this buffer. */
1062 if (NILP (current_buffer->enable_multibyte_characters))
1063 outgoing_nbytes = nchars;
1064 else if (! STRING_MULTIBYTE (string))
1065 outgoing_nbytes
1066 = count_size_as_multibyte (SDATA (string) + pos_byte,
1067 nbytes);
1069 GCPRO1 (string);
1070 /* Do this before moving and increasing the gap,
1071 because the before-change hooks might move the gap
1072 or make it smaller. */
1073 prepare_to_modify_buffer (PT, PT, NULL);
1075 if (PT != GPT)
1076 move_gap_both (PT, PT_BYTE);
1077 if (GAP_SIZE < outgoing_nbytes)
1078 make_gap (outgoing_nbytes - GAP_SIZE);
1079 UNGCPRO;
1081 /* Copy the string text into the buffer, perhaps converting
1082 between single-byte and multibyte. */
1083 copy_text (SDATA (string) + pos_byte, GPT_ADDR, nbytes,
1084 STRING_MULTIBYTE (string),
1085 ! NILP (current_buffer->enable_multibyte_characters));
1087 #ifdef BYTE_COMBINING_DEBUG
1088 /* We have copied text into the gap, but we have not altered
1089 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1090 to these functions and get the same results as we would
1091 have got earlier on. Meanwhile, PT_ADDR does point to
1092 the text that has been stored by copy_text. */
1093 if (count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE)
1094 || count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE))
1095 abort ();
1096 #endif
1098 record_insert (PT, nchars);
1099 MODIFF++;
1100 CHARS_MODIFF = MODIFF;
1102 GAP_SIZE -= outgoing_nbytes;
1103 GPT += nchars;
1104 ZV += nchars;
1105 Z += nchars;
1106 GPT_BYTE += outgoing_nbytes;
1107 ZV_BYTE += outgoing_nbytes;
1108 Z_BYTE += outgoing_nbytes;
1109 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1111 if (GPT_BYTE < GPT)
1112 abort ();
1114 /* The insert may have been in the unchanged region, so check again. */
1115 if (Z - GPT < END_UNCHANGED)
1116 END_UNCHANGED = Z - GPT;
1118 adjust_overlays_for_insert (PT, nchars);
1119 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1120 PT_BYTE + outgoing_nbytes,
1121 before_markers);
1123 offset_intervals (current_buffer, PT, nchars);
1125 intervals = STRING_INTERVALS (string);
1126 /* Get the intervals for the part of the string we are inserting. */
1127 if (nbytes < SBYTES (string))
1128 intervals = copy_intervals (intervals, pos, nchars);
1130 /* Insert those intervals. */
1131 graft_intervals_into_buffer (intervals, PT, nchars,
1132 current_buffer, inherit);
1134 adjust_point (nchars, outgoing_nbytes);
1136 CHECK_MARKERS ();
1139 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1140 starting at GPT_ADDR. */
1142 void
1143 insert_from_gap (EMACS_INT nchars, EMACS_INT nbytes)
1145 if (NILP (current_buffer->enable_multibyte_characters))
1146 nchars = nbytes;
1148 record_insert (GPT, nchars);
1149 MODIFF++;
1151 GAP_SIZE -= nbytes;
1152 GPT += nchars;
1153 ZV += nchars;
1154 Z += nchars;
1155 GPT_BYTE += nbytes;
1156 ZV_BYTE += nbytes;
1157 Z_BYTE += nbytes;
1158 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1160 if (GPT_BYTE < GPT)
1161 abort ();
1163 adjust_overlays_for_insert (GPT - nchars, nchars);
1164 adjust_markers_for_insert (GPT - nchars, GPT_BYTE - nbytes,
1165 GPT, GPT_BYTE, 0);
1167 if (BUF_INTERVALS (current_buffer) != 0)
1169 offset_intervals (current_buffer, GPT - nchars, nchars);
1170 graft_intervals_into_buffer (NULL_INTERVAL, GPT - nchars, nchars,
1171 current_buffer, 0);
1174 if (GPT - nchars < PT)
1175 adjust_point (nchars, nbytes);
1177 CHECK_MARKERS ();
1180 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1181 current buffer. If the text in BUF has properties, they are absorbed
1182 into the current buffer.
1184 It does not work to use `insert' for this, because a malloc could happen
1185 and relocate BUF's text before the bcopy happens. */
1187 void
1188 insert_from_buffer (struct buffer *buf,
1189 EMACS_INT charpos, EMACS_INT nchars, int inherit)
1191 EMACS_INT opoint = PT;
1193 insert_from_buffer_1 (buf, charpos, nchars, inherit);
1194 signal_after_change (opoint, 0, PT - opoint);
1195 update_compositions (opoint, PT, CHECK_BORDER);
1198 static void
1199 insert_from_buffer_1 (struct buffer *buf,
1200 EMACS_INT from, EMACS_INT nchars, int inherit)
1202 register Lisp_Object temp;
1203 EMACS_INT chunk, chunk_expanded;
1204 EMACS_INT from_byte = buf_charpos_to_bytepos (buf, from);
1205 EMACS_INT to_byte = buf_charpos_to_bytepos (buf, from + nchars);
1206 EMACS_INT incoming_nbytes = to_byte - from_byte;
1207 EMACS_INT outgoing_nbytes = incoming_nbytes;
1208 INTERVAL intervals;
1210 /* Make OUTGOING_NBYTES describe the text
1211 as it will be inserted in this buffer. */
1213 if (NILP (current_buffer->enable_multibyte_characters))
1214 outgoing_nbytes = nchars;
1215 else if (NILP (buf->enable_multibyte_characters))
1217 EMACS_INT outgoing_before_gap = 0;
1218 EMACS_INT outgoing_after_gap = 0;
1220 if (from < BUF_GPT (buf))
1222 chunk = BUF_GPT_BYTE (buf) - from_byte;
1223 if (chunk > incoming_nbytes)
1224 chunk = incoming_nbytes;
1225 outgoing_before_gap
1226 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf, from_byte),
1227 chunk);
1229 else
1230 chunk = 0;
1232 if (chunk < incoming_nbytes)
1233 outgoing_after_gap
1234 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf,
1235 from_byte + chunk),
1236 incoming_nbytes - chunk);
1238 outgoing_nbytes = outgoing_before_gap + outgoing_after_gap;
1241 /* Make sure point-max won't overflow after this insertion. */
1242 XSETINT (temp, outgoing_nbytes + Z);
1243 if (outgoing_nbytes + Z != XINT (temp))
1244 error ("Maximum buffer size exceeded");
1246 /* Do this before moving and increasing the gap,
1247 because the before-change hooks might move the gap
1248 or make it smaller. */
1249 prepare_to_modify_buffer (PT, PT, NULL);
1251 if (PT != GPT)
1252 move_gap_both (PT, PT_BYTE);
1253 if (GAP_SIZE < outgoing_nbytes)
1254 make_gap (outgoing_nbytes - GAP_SIZE);
1256 if (from < BUF_GPT (buf))
1258 chunk = BUF_GPT_BYTE (buf) - from_byte;
1259 if (chunk > incoming_nbytes)
1260 chunk = incoming_nbytes;
1261 /* Record number of output bytes, so we know where
1262 to put the output from the second copy_text. */
1263 chunk_expanded
1264 = copy_text (BUF_BYTE_ADDRESS (buf, from_byte),
1265 GPT_ADDR, chunk,
1266 ! NILP (buf->enable_multibyte_characters),
1267 ! NILP (current_buffer->enable_multibyte_characters));
1269 else
1270 chunk_expanded = chunk = 0;
1272 if (chunk < incoming_nbytes)
1273 copy_text (BUF_BYTE_ADDRESS (buf, from_byte + chunk),
1274 GPT_ADDR + chunk_expanded, incoming_nbytes - chunk,
1275 ! NILP (buf->enable_multibyte_characters),
1276 ! NILP (current_buffer->enable_multibyte_characters));
1278 #ifdef BYTE_COMBINING_DEBUG
1279 /* We have copied text into the gap, but we have not altered
1280 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1281 to these functions and get the same results as we would
1282 have got earlier on. Meanwhile, GPT_ADDR does point to
1283 the text that has been stored by copy_text. */
1284 if (count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE)
1285 || count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE))
1286 abort ();
1287 #endif
1289 record_insert (PT, nchars);
1290 MODIFF++;
1291 CHARS_MODIFF = MODIFF;
1293 GAP_SIZE -= outgoing_nbytes;
1294 GPT += nchars;
1295 ZV += nchars;
1296 Z += nchars;
1297 GPT_BYTE += outgoing_nbytes;
1298 ZV_BYTE += outgoing_nbytes;
1299 Z_BYTE += outgoing_nbytes;
1300 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1302 if (GPT_BYTE < GPT)
1303 abort ();
1305 /* The insert may have been in the unchanged region, so check again. */
1306 if (Z - GPT < END_UNCHANGED)
1307 END_UNCHANGED = Z - GPT;
1309 adjust_overlays_for_insert (PT, nchars);
1310 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1311 PT_BYTE + outgoing_nbytes,
1314 if (BUF_INTERVALS (current_buffer) != 0)
1315 offset_intervals (current_buffer, PT, nchars);
1317 /* Get the intervals for the part of the string we are inserting. */
1318 intervals = BUF_INTERVALS (buf);
1319 if (nchars < BUF_Z (buf) - BUF_BEG (buf))
1321 if (buf == current_buffer && PT <= from)
1322 from += nchars;
1323 intervals = copy_intervals (intervals, from, nchars);
1326 /* Insert those intervals. */
1327 graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
1329 adjust_point (nchars, outgoing_nbytes);
1332 /* Record undo information and adjust markers and position keepers for
1333 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1334 chars (LEN_BYTE bytes) which resides in the gap just after
1335 GPT_ADDR.
1337 PREV_TEXT nil means the new text was just inserted. */
1339 void
1340 adjust_after_replace (EMACS_INT from, EMACS_INT from_byte,
1341 Lisp_Object prev_text, EMACS_INT len, EMACS_INT len_byte)
1343 EMACS_INT nchars_del = 0, nbytes_del = 0;
1345 #ifdef BYTE_COMBINING_DEBUG
1346 if (count_combining_before (GPT_ADDR, len_byte, from, from_byte)
1347 || count_combining_after (GPT_ADDR, len_byte, from, from_byte))
1348 abort ();
1349 #endif
1351 if (STRINGP (prev_text))
1353 nchars_del = SCHARS (prev_text);
1354 nbytes_del = SBYTES (prev_text);
1357 /* Update various buffer positions for the new text. */
1358 GAP_SIZE -= len_byte;
1359 ZV += len; Z+= len;
1360 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1361 GPT += len; GPT_BYTE += len_byte;
1362 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1364 if (nchars_del > 0)
1365 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1366 len, len_byte);
1367 else
1368 adjust_markers_for_insert (from, from_byte,
1369 from + len, from_byte + len_byte, 0);
1371 if (! EQ (current_buffer->undo_list, Qt))
1373 if (nchars_del > 0)
1374 record_delete (from, prev_text);
1375 record_insert (from, len);
1378 if (len > nchars_del)
1379 adjust_overlays_for_insert (from, len - nchars_del);
1380 else if (len < nchars_del)
1381 adjust_overlays_for_delete (from, nchars_del - len);
1382 if (BUF_INTERVALS (current_buffer) != 0)
1384 offset_intervals (current_buffer, from, len - nchars_del);
1387 if (from < PT)
1388 adjust_point (len - nchars_del, len_byte - nbytes_del);
1390 /* As byte combining will decrease Z, we must check this again. */
1391 if (Z - GPT < END_UNCHANGED)
1392 END_UNCHANGED = Z - GPT;
1394 CHECK_MARKERS ();
1396 if (len == 0)
1397 evaporate_overlays (from);
1398 MODIFF++;
1399 CHARS_MODIFF = MODIFF;
1402 /* Like adjust_after_replace, but doesn't require PREV_TEXT.
1403 This is for use when undo is not enabled in the current buffer. */
1405 void
1406 adjust_after_replace_noundo (EMACS_INT from, EMACS_INT from_byte,
1407 EMACS_INT nchars_del, EMACS_INT nbytes_del,
1408 EMACS_INT len, EMACS_INT len_byte)
1410 #ifdef BYTE_COMBINING_DEBUG
1411 if (count_combining_before (GPT_ADDR, len_byte, from, from_byte)
1412 || count_combining_after (GPT_ADDR, len_byte, from, from_byte))
1413 abort ();
1414 #endif
1416 /* Update various buffer positions for the new text. */
1417 GAP_SIZE -= len_byte;
1418 ZV += len; Z+= len;
1419 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1420 GPT += len; GPT_BYTE += len_byte;
1421 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1423 if (nchars_del > 0)
1424 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1425 len, len_byte);
1426 else
1427 adjust_markers_for_insert (from, from_byte,
1428 from + len, from_byte + len_byte, 0);
1430 if (len > nchars_del)
1431 adjust_overlays_for_insert (from, len - nchars_del);
1432 else if (len < nchars_del)
1433 adjust_overlays_for_delete (from, nchars_del - len);
1434 if (BUF_INTERVALS (current_buffer) != 0)
1436 offset_intervals (current_buffer, from, len - nchars_del);
1439 if (from < PT)
1440 adjust_point (len - nchars_del, len_byte - nbytes_del);
1442 /* As byte combining will decrease Z, we must check this again. */
1443 if (Z - GPT < END_UNCHANGED)
1444 END_UNCHANGED = Z - GPT;
1446 CHECK_MARKERS ();
1448 if (len == 0)
1449 evaporate_overlays (from);
1450 MODIFF++;
1451 CHARS_MODIFF = MODIFF;
1454 /* Record undo information, adjust markers and position keepers for an
1455 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1456 text already exists in the current buffer but character length (TO
1457 - FROM) may be incorrect, the correct length is NEWLEN. */
1459 void
1460 adjust_after_insert (EMACS_INT from, EMACS_INT from_byte,
1461 EMACS_INT to, EMACS_INT to_byte, EMACS_INT newlen)
1463 EMACS_INT len = to - from, len_byte = to_byte - from_byte;
1465 if (GPT != to)
1466 move_gap_both (to, to_byte);
1467 GAP_SIZE += len_byte;
1468 GPT -= len; GPT_BYTE -= len_byte;
1469 ZV -= len; ZV_BYTE -= len_byte;
1470 Z -= len; Z_BYTE -= len_byte;
1471 adjust_after_replace (from, from_byte, Qnil, newlen, len_byte);
1474 /* Replace the text from character positions FROM to TO with NEW,
1475 If PREPARE is nonzero, call prepare_to_modify_buffer.
1476 If INHERIT, the newly inserted text should inherit text properties
1477 from the surrounding non-deleted text. */
1479 /* Note that this does not yet handle markers quite right.
1480 Also it needs to record a single undo-entry that does a replacement
1481 rather than a separate delete and insert.
1482 That way, undo will also handle markers properly.
1484 But if MARKERS is 0, don't relocate markers. */
1486 void
1487 replace_range (EMACS_INT from, EMACS_INT to, Lisp_Object new,
1488 int prepare, int inherit, int markers)
1490 EMACS_INT inschars = SCHARS (new);
1491 EMACS_INT insbytes = SBYTES (new);
1492 EMACS_INT from_byte, to_byte;
1493 EMACS_INT nbytes_del, nchars_del;
1494 register Lisp_Object temp;
1495 struct gcpro gcpro1;
1496 INTERVAL intervals;
1497 EMACS_INT outgoing_insbytes = insbytes;
1498 Lisp_Object deletion;
1500 CHECK_MARKERS ();
1502 GCPRO1 (new);
1503 deletion = Qnil;
1505 if (prepare)
1507 EMACS_INT range_length = to - from;
1508 prepare_to_modify_buffer (from, to, &from);
1509 to = from + range_length;
1512 UNGCPRO;
1514 /* Make args be valid */
1515 if (from < BEGV)
1516 from = BEGV;
1517 if (to > ZV)
1518 to = ZV;
1520 from_byte = CHAR_TO_BYTE (from);
1521 to_byte = CHAR_TO_BYTE (to);
1523 nchars_del = to - from;
1524 nbytes_del = to_byte - from_byte;
1526 if (nbytes_del <= 0 && insbytes == 0)
1527 return;
1529 /* Make OUTGOING_INSBYTES describe the text
1530 as it will be inserted in this buffer. */
1532 if (NILP (current_buffer->enable_multibyte_characters))
1533 outgoing_insbytes = inschars;
1534 else if (! STRING_MULTIBYTE (new))
1535 outgoing_insbytes
1536 = count_size_as_multibyte (SDATA (new), insbytes);
1538 /* Make sure point-max won't overflow after this insertion. */
1539 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1540 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1541 error ("Maximum buffer size exceeded");
1543 GCPRO1 (new);
1545 /* Make sure the gap is somewhere in or next to what we are deleting. */
1546 if (from > GPT)
1547 gap_right (from, from_byte);
1548 if (to < GPT)
1549 gap_left (to, to_byte, 0);
1551 /* Even if we don't record for undo, we must keep the original text
1552 because we may have to recover it because of inappropriate byte
1553 combining. */
1554 if (! EQ (current_buffer->undo_list, Qt))
1555 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1557 GAP_SIZE += nbytes_del;
1558 ZV -= nchars_del;
1559 Z -= nchars_del;
1560 ZV_BYTE -= nbytes_del;
1561 Z_BYTE -= nbytes_del;
1562 GPT = from;
1563 GPT_BYTE = from_byte;
1564 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1566 if (GPT_BYTE < GPT)
1567 abort ();
1569 if (GPT - BEG < BEG_UNCHANGED)
1570 BEG_UNCHANGED = GPT - BEG;
1571 if (Z - GPT < END_UNCHANGED)
1572 END_UNCHANGED = Z - GPT;
1574 if (GAP_SIZE < insbytes)
1575 make_gap (insbytes - GAP_SIZE);
1577 /* Copy the string text into the buffer, perhaps converting
1578 between single-byte and multibyte. */
1579 copy_text (SDATA (new), GPT_ADDR, insbytes,
1580 STRING_MULTIBYTE (new),
1581 ! NILP (current_buffer->enable_multibyte_characters));
1583 #ifdef BYTE_COMBINING_DEBUG
1584 /* We have copied text into the gap, but we have not marked
1585 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1586 here, for both the previous text and the following text.
1587 Meanwhile, GPT_ADDR does point to
1588 the text that has been stored by copy_text. */
1589 if (count_combining_before (GPT_ADDR, outgoing_insbytes, from, from_byte)
1590 || count_combining_after (GPT_ADDR, outgoing_insbytes, from, from_byte))
1591 abort ();
1592 #endif
1594 if (! EQ (current_buffer->undo_list, Qt))
1596 /* Record the insertion first, so that when we undo,
1597 the deletion will be undone first. Thus, undo
1598 will insert before deleting, and thus will keep
1599 the markers before and after this text separate. */
1600 record_insert (from + SCHARS (deletion), inschars);
1601 record_delete (from, deletion);
1604 GAP_SIZE -= outgoing_insbytes;
1605 GPT += inschars;
1606 ZV += inschars;
1607 Z += inschars;
1608 GPT_BYTE += outgoing_insbytes;
1609 ZV_BYTE += outgoing_insbytes;
1610 Z_BYTE += outgoing_insbytes;
1611 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1613 if (GPT_BYTE < GPT)
1614 abort ();
1616 /* Adjust the overlay center as needed. This must be done after
1617 adjusting the markers that bound the overlays. */
1618 adjust_overlays_for_delete (from, nchars_del);
1619 adjust_overlays_for_insert (from, inschars);
1621 /* Adjust markers for the deletion and the insertion. */
1622 if (markers)
1623 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1624 inschars, outgoing_insbytes);
1626 offset_intervals (current_buffer, from, inschars - nchars_del);
1628 /* Get the intervals for the part of the string we are inserting--
1629 not including the combined-before bytes. */
1630 intervals = STRING_INTERVALS (new);
1631 /* Insert those intervals. */
1632 graft_intervals_into_buffer (intervals, from, inschars,
1633 current_buffer, inherit);
1635 /* Relocate point as if it were a marker. */
1636 if (from < PT)
1637 adjust_point ((from + inschars - (PT < to ? PT : to)),
1638 (from_byte + outgoing_insbytes
1639 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
1641 if (outgoing_insbytes == 0)
1642 evaporate_overlays (from);
1644 CHECK_MARKERS ();
1646 MODIFF++;
1647 CHARS_MODIFF = MODIFF;
1648 UNGCPRO;
1650 signal_after_change (from, nchars_del, GPT - from);
1651 update_compositions (from, GPT, CHECK_BORDER);
1654 /* Replace the text from character positions FROM to TO with
1655 the text in INS of length INSCHARS.
1656 Keep the text properties that applied to the old characters
1657 (extending them to all the new chars if there are more new chars).
1659 Note that this does not yet handle markers quite right.
1661 If MARKERS is nonzero, relocate markers.
1663 Unlike most functions at this level, never call
1664 prepare_to_modify_buffer and never call signal_after_change. */
1666 void
1667 replace_range_2 (EMACS_INT from, EMACS_INT from_byte,
1668 EMACS_INT to, EMACS_INT to_byte,
1669 char *ins, EMACS_INT inschars, EMACS_INT insbytes,
1670 int markers)
1672 EMACS_INT nbytes_del, nchars_del;
1673 Lisp_Object temp;
1675 CHECK_MARKERS ();
1677 nchars_del = to - from;
1678 nbytes_del = to_byte - from_byte;
1680 if (nbytes_del <= 0 && insbytes == 0)
1681 return;
1683 /* Make sure point-max won't overflow after this insertion. */
1684 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1685 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1686 error ("Maximum buffer size exceeded");
1688 /* Make sure the gap is somewhere in or next to what we are deleting. */
1689 if (from > GPT)
1690 gap_right (from, from_byte);
1691 if (to < GPT)
1692 gap_left (to, to_byte, 0);
1694 GAP_SIZE += nbytes_del;
1695 ZV -= nchars_del;
1696 Z -= nchars_del;
1697 ZV_BYTE -= nbytes_del;
1698 Z_BYTE -= nbytes_del;
1699 GPT = from;
1700 GPT_BYTE = from_byte;
1701 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1703 if (GPT_BYTE < GPT)
1704 abort ();
1706 if (GPT - BEG < BEG_UNCHANGED)
1707 BEG_UNCHANGED = GPT - BEG;
1708 if (Z - GPT < END_UNCHANGED)
1709 END_UNCHANGED = Z - GPT;
1711 if (GAP_SIZE < insbytes)
1712 make_gap (insbytes - GAP_SIZE);
1714 /* Copy the replacement text into the buffer. */
1715 bcopy (ins, GPT_ADDR, insbytes);
1717 #ifdef BYTE_COMBINING_DEBUG
1718 /* We have copied text into the gap, but we have not marked
1719 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1720 here, for both the previous text and the following text.
1721 Meanwhile, GPT_ADDR does point to
1722 the text that has been stored by copy_text. */
1723 if (count_combining_before (GPT_ADDR, insbytes, from, from_byte)
1724 || count_combining_after (GPT_ADDR, insbytes, from, from_byte))
1725 abort ();
1726 #endif
1728 GAP_SIZE -= insbytes;
1729 GPT += inschars;
1730 ZV += inschars;
1731 Z += inschars;
1732 GPT_BYTE += insbytes;
1733 ZV_BYTE += insbytes;
1734 Z_BYTE += insbytes;
1735 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1737 if (GPT_BYTE < GPT)
1738 abort ();
1740 /* Adjust the overlay center as needed. This must be done after
1741 adjusting the markers that bound the overlays. */
1742 if (nchars_del != inschars)
1744 adjust_overlays_for_insert (from, inschars);
1745 adjust_overlays_for_delete (from + inschars, nchars_del);
1748 /* Adjust markers for the deletion and the insertion. */
1749 if (markers
1750 && ! (nchars_del == 1 && inschars == 1 && nbytes_del == insbytes))
1751 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1752 inschars, insbytes);
1754 offset_intervals (current_buffer, from, inschars - nchars_del);
1756 /* Relocate point as if it were a marker. */
1757 if (from < PT && (nchars_del != inschars || nbytes_del != insbytes))
1759 if (PT < to)
1760 /* PT was within the deleted text. Move it to FROM. */
1761 adjust_point (from - PT, from_byte - PT_BYTE);
1762 else
1763 adjust_point (inschars - nchars_del, insbytes - nbytes_del);
1766 if (insbytes == 0)
1767 evaporate_overlays (from);
1769 CHECK_MARKERS ();
1771 MODIFF++;
1772 CHARS_MODIFF = MODIFF;
1775 /* Delete characters in current buffer
1776 from FROM up to (but not including) TO.
1777 If TO comes before FROM, we delete nothing. */
1779 void
1780 del_range (EMACS_INT from, EMACS_INT to)
1782 del_range_1 (from, to, 1, 0);
1785 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1786 RET_STRING says to return the deleted text. */
1788 Lisp_Object
1789 del_range_1 (EMACS_INT from, EMACS_INT to, int prepare, int ret_string)
1791 EMACS_INT from_byte, to_byte;
1792 Lisp_Object deletion;
1793 struct gcpro gcpro1;
1795 /* Make args be valid */
1796 if (from < BEGV)
1797 from = BEGV;
1798 if (to > ZV)
1799 to = ZV;
1801 if (to <= from)
1802 return Qnil;
1804 if (prepare)
1806 EMACS_INT range_length = to - from;
1807 prepare_to_modify_buffer (from, to, &from);
1808 to = min (ZV, from + range_length);
1811 from_byte = CHAR_TO_BYTE (from);
1812 to_byte = CHAR_TO_BYTE (to);
1814 deletion = del_range_2 (from, from_byte, to, to_byte, ret_string);
1815 GCPRO1(deletion);
1816 signal_after_change (from, to - from, 0);
1817 update_compositions (from, from, CHECK_HEAD);
1818 UNGCPRO;
1819 return deletion;
1822 /* Like del_range_1 but args are byte positions, not char positions. */
1824 void
1825 del_range_byte (EMACS_INT from_byte, EMACS_INT to_byte, int prepare)
1827 EMACS_INT from, to;
1829 /* Make args be valid */
1830 if (from_byte < BEGV_BYTE)
1831 from_byte = BEGV_BYTE;
1832 if (to_byte > ZV_BYTE)
1833 to_byte = ZV_BYTE;
1835 if (to_byte <= from_byte)
1836 return;
1838 from = BYTE_TO_CHAR (from_byte);
1839 to = BYTE_TO_CHAR (to_byte);
1841 if (prepare)
1843 EMACS_INT old_from = from, old_to = Z - to;
1844 EMACS_INT range_length = to - from;
1845 prepare_to_modify_buffer (from, to, &from);
1846 to = from + range_length;
1848 if (old_from != from)
1849 from_byte = CHAR_TO_BYTE (from);
1850 if (to > ZV)
1852 to = ZV;
1853 to_byte = ZV_BYTE;
1855 else if (old_to == Z - to)
1856 to_byte = CHAR_TO_BYTE (to);
1859 del_range_2 (from, from_byte, to, to_byte, 0);
1860 signal_after_change (from, to - from, 0);
1861 update_compositions (from, from, CHECK_HEAD);
1864 /* Like del_range_1, but positions are specified both as charpos
1865 and bytepos. */
1867 void
1868 del_range_both (EMACS_INT from, EMACS_INT from_byte,
1869 EMACS_INT to, EMACS_INT to_byte, int prepare)
1871 /* Make args be valid */
1872 if (from_byte < BEGV_BYTE)
1873 from_byte = BEGV_BYTE;
1874 if (to_byte > ZV_BYTE)
1875 to_byte = ZV_BYTE;
1877 if (to_byte <= from_byte)
1878 return;
1880 if (from < BEGV)
1881 from = BEGV;
1882 if (to > ZV)
1883 to = ZV;
1885 if (prepare)
1887 EMACS_INT old_from = from, old_to = Z - to;
1888 EMACS_INT range_length = to - from;
1889 prepare_to_modify_buffer (from, to, &from);
1890 to = from + range_length;
1892 if (old_from != from)
1893 from_byte = CHAR_TO_BYTE (from);
1894 if (to > ZV)
1896 to = ZV;
1897 to_byte = ZV_BYTE;
1899 else if (old_to == Z - to)
1900 to_byte = CHAR_TO_BYTE (to);
1903 del_range_2 (from, from_byte, to, to_byte, 0);
1904 signal_after_change (from, to - from, 0);
1905 update_compositions (from, from, CHECK_HEAD);
1908 /* Delete a range of text, specified both as character positions
1909 and byte positions. FROM and TO are character positions,
1910 while FROM_BYTE and TO_BYTE are byte positions.
1911 If RET_STRING is true, the deleted area is returned as a string. */
1913 Lisp_Object
1914 del_range_2 (EMACS_INT from, EMACS_INT from_byte,
1915 EMACS_INT to, EMACS_INT to_byte, int ret_string)
1917 register EMACS_INT nbytes_del, nchars_del;
1918 Lisp_Object deletion;
1920 CHECK_MARKERS ();
1922 nchars_del = to - from;
1923 nbytes_del = to_byte - from_byte;
1925 /* Make sure the gap is somewhere in or next to what we are deleting. */
1926 if (from > GPT)
1927 gap_right (from, from_byte);
1928 if (to < GPT)
1929 gap_left (to, to_byte, 0);
1931 #ifdef BYTE_COMBINING_DEBUG
1932 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte),
1933 Z_BYTE - to_byte, from, from_byte))
1934 abort ();
1935 #endif
1937 if (ret_string || ! EQ (current_buffer->undo_list, Qt))
1938 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1939 else
1940 deletion = Qnil;
1942 /* Relocate all markers pointing into the new, larger gap
1943 to point at the end of the text before the gap.
1944 Do this before recording the deletion,
1945 so that undo handles this after reinserting the text. */
1946 adjust_markers_for_delete (from, from_byte, to, to_byte);
1948 if (! EQ (current_buffer->undo_list, Qt))
1949 record_delete (from, deletion);
1950 MODIFF++;
1951 CHARS_MODIFF = MODIFF;
1953 /* Relocate point as if it were a marker. */
1954 if (from < PT)
1955 adjust_point (from - (PT < to ? PT : to),
1956 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte));
1958 offset_intervals (current_buffer, from, - nchars_del);
1960 /* Adjust the overlay center as needed. This must be done after
1961 adjusting the markers that bound the overlays. */
1962 adjust_overlays_for_delete (from, nchars_del);
1964 GAP_SIZE += nbytes_del;
1965 ZV_BYTE -= nbytes_del;
1966 Z_BYTE -= nbytes_del;
1967 ZV -= nchars_del;
1968 Z -= nchars_del;
1969 GPT = from;
1970 GPT_BYTE = from_byte;
1971 if (GAP_SIZE > 0 && !current_buffer->text->inhibit_shrinking)
1972 /* Put an anchor, unless called from decode_coding_object which
1973 needs to access the previous gap contents. */
1974 *(GPT_ADDR) = 0;
1976 if (GPT_BYTE < GPT)
1977 abort ();
1979 if (GPT - BEG < BEG_UNCHANGED)
1980 BEG_UNCHANGED = GPT - BEG;
1981 if (Z - GPT < END_UNCHANGED)
1982 END_UNCHANGED = Z - GPT;
1984 CHECK_MARKERS ();
1986 evaporate_overlays (from);
1988 return deletion;
1991 /* Call this if you're about to change the region of BUFFER from
1992 character positions START to END. This checks the read-only
1993 properties of the region, calls the necessary modification hooks,
1994 and warns the next redisplay that it should pay attention to that
1995 area.
1997 If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
1998 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
2000 void
2001 modify_region (struct buffer *buffer, EMACS_INT start, EMACS_INT end,
2002 int preserve_chars_modiff)
2004 struct buffer *old_buffer = current_buffer;
2006 if (buffer != old_buffer)
2007 set_buffer_internal (buffer);
2009 prepare_to_modify_buffer (start, end, NULL);
2011 BUF_COMPUTE_UNCHANGED (buffer, start - 1, end);
2013 if (MODIFF <= SAVE_MODIFF)
2014 record_first_change ();
2015 MODIFF++;
2016 if (! preserve_chars_modiff)
2017 CHARS_MODIFF = MODIFF;
2019 buffer->point_before_scroll = Qnil;
2021 if (buffer != old_buffer)
2022 set_buffer_internal (old_buffer);
2025 /* Check that it is okay to modify the buffer between START and END,
2026 which are char positions.
2028 Run the before-change-function, if any. If intervals are in use,
2029 verify that the text to be modified is not read-only, and call
2030 any modification properties the text may have.
2032 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2033 by holding its value temporarily in a marker. */
2035 void
2036 prepare_to_modify_buffer (EMACS_INT start, EMACS_INT end,
2037 EMACS_INT *preserve_ptr)
2039 struct buffer *base_buffer;
2041 if (!NILP (current_buffer->read_only))
2042 Fbarf_if_buffer_read_only ();
2044 /* Let redisplay consider other windows than selected_window
2045 if modifying another buffer. */
2046 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
2047 ++windows_or_buffers_changed;
2049 if (BUF_INTERVALS (current_buffer) != 0)
2051 if (preserve_ptr)
2053 Lisp_Object preserve_marker;
2054 struct gcpro gcpro1;
2055 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
2056 GCPRO1 (preserve_marker);
2057 verify_interval_modification (current_buffer, start, end);
2058 *preserve_ptr = marker_position (preserve_marker);
2059 unchain_marker (XMARKER (preserve_marker));
2060 UNGCPRO;
2062 else
2063 verify_interval_modification (current_buffer, start, end);
2066 /* For indirect buffers, use the base buffer to check clashes. */
2067 if (current_buffer->base_buffer != 0)
2068 base_buffer = current_buffer->base_buffer;
2069 else
2070 base_buffer = current_buffer;
2072 #ifdef CLASH_DETECTION
2073 if (!NILP (base_buffer->file_truename)
2074 /* Make binding buffer-file-name to nil effective. */
2075 && !NILP (base_buffer->filename)
2076 && SAVE_MODIFF >= MODIFF)
2077 lock_file (base_buffer->file_truename);
2078 #else
2079 /* At least warn if this file has changed on disk since it was visited. */
2080 if (!NILP (base_buffer->filename)
2081 && SAVE_MODIFF >= MODIFF
2082 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2083 && !NILP (Ffile_exists_p (base_buffer->filename)))
2084 call1 (intern ("ask-user-about-supersession-threat"),
2085 base_buffer->filename);
2086 #endif /* not CLASH_DETECTION */
2088 signal_before_change (start, end, preserve_ptr);
2090 if (current_buffer->newline_cache)
2091 invalidate_region_cache (current_buffer,
2092 current_buffer->newline_cache,
2093 start - BEG, Z - end);
2094 if (current_buffer->width_run_cache)
2095 invalidate_region_cache (current_buffer,
2096 current_buffer->width_run_cache,
2097 start - BEG, Z - end);
2099 Vdeactivate_mark = Qt;
2102 /* These macros work with an argument named `preserve_ptr'
2103 and a local variable named `preserve_marker'. */
2105 #define PRESERVE_VALUE \
2106 if (preserve_ptr && NILP (preserve_marker)) \
2107 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2109 #define RESTORE_VALUE \
2110 if (! NILP (preserve_marker)) \
2112 *preserve_ptr = marker_position (preserve_marker); \
2113 unchain_marker (XMARKER (preserve_marker)); \
2116 #define PRESERVE_START_END \
2117 if (NILP (start_marker)) \
2118 start_marker = Fcopy_marker (start, Qnil); \
2119 if (NILP (end_marker)) \
2120 end_marker = Fcopy_marker (end, Qnil);
2122 #define FETCH_START \
2123 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2125 #define FETCH_END \
2126 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2128 /* Set a variable to nil if an error occurred.
2129 Don't change the variable if there was no error.
2130 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
2131 VARIABLE is the variable to maybe set to nil.
2132 NO-ERROR-FLAG is nil if there was an error,
2133 anything else meaning no error (so this function does nothing). */
2134 Lisp_Object
2135 reset_var_on_error (val)
2136 Lisp_Object val;
2138 if (NILP (XCDR (val)))
2139 Fset (XCAR (val), Qnil);
2140 return Qnil;
2143 /* Signal a change to the buffer immediately before it happens.
2144 START_INT and END_INT are the bounds of the text to be changed.
2146 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2147 by holding its value temporarily in a marker. */
2149 void
2150 signal_before_change (EMACS_INT start_int, EMACS_INT end_int,
2151 EMACS_INT *preserve_ptr)
2153 Lisp_Object start, end;
2154 Lisp_Object start_marker, end_marker;
2155 Lisp_Object preserve_marker;
2156 struct gcpro gcpro1, gcpro2, gcpro3;
2157 int count = SPECPDL_INDEX ();
2159 if (inhibit_modification_hooks)
2160 return;
2162 start = make_number (start_int);
2163 end = make_number (end_int);
2164 preserve_marker = Qnil;
2165 start_marker = Qnil;
2166 end_marker = Qnil;
2167 GCPRO3 (preserve_marker, start_marker, end_marker);
2169 specbind (Qinhibit_modification_hooks, Qt);
2171 /* If buffer is unmodified, run a special hook for that case. */
2172 if (SAVE_MODIFF >= MODIFF
2173 && !NILP (Vfirst_change_hook)
2174 && !NILP (Vrun_hooks))
2176 PRESERVE_VALUE;
2177 PRESERVE_START_END;
2178 call1 (Vrun_hooks, Qfirst_change_hook);
2181 /* Now run the before-change-functions if any. */
2182 if (!NILP (Vbefore_change_functions))
2184 Lisp_Object args[3];
2185 Lisp_Object rvoe_arg = Fcons (Qbefore_change_functions, Qnil);
2187 PRESERVE_VALUE;
2188 PRESERVE_START_END;
2190 /* Mark before-change-functions to be reset to nil in case of error. */
2191 record_unwind_protect (reset_var_on_error, rvoe_arg);
2193 /* Actually run the hook functions. */
2194 args[0] = Qbefore_change_functions;
2195 args[1] = FETCH_START;
2196 args[2] = FETCH_END;
2197 Frun_hook_with_args (3, args);
2199 /* There was no error: unarm the reset_on_error. */
2200 XSETCDR (rvoe_arg, Qt);
2203 if (current_buffer->overlays_before || current_buffer->overlays_after)
2205 PRESERVE_VALUE;
2206 report_overlay_modification (FETCH_START, FETCH_END, 0,
2207 FETCH_START, FETCH_END, Qnil);
2210 if (! NILP (start_marker))
2211 free_marker (start_marker);
2212 if (! NILP (end_marker))
2213 free_marker (end_marker);
2214 RESTORE_VALUE;
2215 UNGCPRO;
2217 unbind_to (count, Qnil);
2220 /* Signal a change immediately after it happens.
2221 CHARPOS is the character position of the start of the changed text.
2222 LENDEL is the number of characters of the text before the change.
2223 (Not the whole buffer; just the part that was changed.)
2224 LENINS is the number of characters in that part of the text
2225 after the change. */
2227 void
2228 signal_after_change (EMACS_INT charpos, EMACS_INT lendel, EMACS_INT lenins)
2230 int count = SPECPDL_INDEX ();
2231 if (inhibit_modification_hooks)
2232 return;
2234 /* If we are deferring calls to the after-change functions
2235 and there are no before-change functions,
2236 just record the args that we were going to use. */
2237 if (! NILP (Vcombine_after_change_calls)
2238 && NILP (Vbefore_change_functions)
2239 && !current_buffer->overlays_before
2240 && !current_buffer->overlays_after)
2242 Lisp_Object elt;
2244 if (!NILP (combine_after_change_list)
2245 && current_buffer != XBUFFER (combine_after_change_buffer))
2246 Fcombine_after_change_execute ();
2248 elt = Fcons (make_number (charpos - BEG),
2249 Fcons (make_number (Z - (charpos - lendel + lenins)),
2250 Fcons (make_number (lenins - lendel), Qnil)));
2251 combine_after_change_list
2252 = Fcons (elt, combine_after_change_list);
2253 combine_after_change_buffer = Fcurrent_buffer ();
2255 return;
2258 if (!NILP (combine_after_change_list))
2259 Fcombine_after_change_execute ();
2261 specbind (Qinhibit_modification_hooks, Qt);
2263 if (!NILP (Vafter_change_functions))
2265 Lisp_Object args[4];
2266 Lisp_Object rvoe_arg = Fcons (Qafter_change_functions, Qnil);
2268 /* Mark after-change-functions to be reset to nil in case of error. */
2269 record_unwind_protect (reset_var_on_error, rvoe_arg);
2271 /* Actually run the hook functions. */
2272 args[0] = Qafter_change_functions;
2273 XSETFASTINT (args[1], charpos);
2274 XSETFASTINT (args[2], charpos + lenins);
2275 XSETFASTINT (args[3], lendel);
2276 Frun_hook_with_args (4, args);
2278 /* There was no error: unarm the reset_on_error. */
2279 XSETCDR (rvoe_arg, Qt);
2282 if (current_buffer->overlays_before || current_buffer->overlays_after)
2283 report_overlay_modification (make_number (charpos),
2284 make_number (charpos + lenins),
2286 make_number (charpos),
2287 make_number (charpos + lenins),
2288 make_number (lendel));
2290 /* After an insertion, call the text properties
2291 insert-behind-hooks or insert-in-front-hooks. */
2292 if (lendel == 0)
2293 report_interval_modification (make_number (charpos),
2294 make_number (charpos + lenins));
2296 unbind_to (count, Qnil);
2299 Lisp_Object
2300 Fcombine_after_change_execute_1 (val)
2301 Lisp_Object val;
2303 Vcombine_after_change_calls = val;
2304 return val;
2307 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
2308 Scombine_after_change_execute, 0, 0, 0,
2309 doc: /* This function is for use internally in `combine-after-change-calls'. */)
2312 int count = SPECPDL_INDEX ();
2313 EMACS_INT beg, end, change;
2314 EMACS_INT begpos, endpos;
2315 Lisp_Object tail;
2317 if (NILP (combine_after_change_list))
2318 return Qnil;
2320 /* It is rare for combine_after_change_buffer to be invalid, but
2321 possible. It can happen when combine-after-change-calls is
2322 non-nil, and insertion calls a file handler (e.g. through
2323 lock_file) which scribbles into a temp file -- cyd */
2324 if (!BUFFERP (combine_after_change_buffer)
2325 || NILP (XBUFFER (combine_after_change_buffer)->name))
2327 combine_after_change_list = Qnil;
2328 return Qnil;
2331 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
2333 Fset_buffer (combine_after_change_buffer);
2335 /* # chars unchanged at beginning of buffer. */
2336 beg = Z - BEG;
2337 /* # chars unchanged at end of buffer. */
2338 end = beg;
2339 /* Total amount of insertion (negative for deletion). */
2340 change = 0;
2342 /* Scan the various individual changes,
2343 accumulating the range info in BEG, END and CHANGE. */
2344 for (tail = combine_after_change_list; CONSP (tail);
2345 tail = XCDR (tail))
2347 Lisp_Object elt;
2348 EMACS_INT thisbeg, thisend, thischange;
2350 /* Extract the info from the next element. */
2351 elt = XCAR (tail);
2352 if (! CONSP (elt))
2353 continue;
2354 thisbeg = XINT (XCAR (elt));
2356 elt = XCDR (elt);
2357 if (! CONSP (elt))
2358 continue;
2359 thisend = XINT (XCAR (elt));
2361 elt = XCDR (elt);
2362 if (! CONSP (elt))
2363 continue;
2364 thischange = XINT (XCAR (elt));
2366 /* Merge this range into the accumulated range. */
2367 change += thischange;
2368 if (thisbeg < beg)
2369 beg = thisbeg;
2370 if (thisend < end)
2371 end = thisend;
2374 /* Get the current start and end positions of the range
2375 that was changed. */
2376 begpos = BEG + beg;
2377 endpos = Z - end;
2379 /* We are about to handle these, so discard them. */
2380 combine_after_change_list = Qnil;
2382 /* Now run the after-change functions for real.
2383 Turn off the flag that defers them. */
2384 record_unwind_protect (Fcombine_after_change_execute_1,
2385 Vcombine_after_change_calls);
2386 signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
2387 update_compositions (begpos, endpos, CHECK_ALL);
2389 return unbind_to (count, Qnil);
2392 void
2393 syms_of_insdel ()
2395 staticpro (&combine_after_change_list);
2396 staticpro (&combine_after_change_buffer);
2397 combine_after_change_list = Qnil;
2398 combine_after_change_buffer = Qnil;
2400 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag,
2401 doc: /* Non-nil means enable debugging checks for invalid marker positions. */);
2402 check_markers_debug_flag = 0;
2403 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
2404 doc: /* Used internally by the `combine-after-change-calls' macro. */);
2405 Vcombine_after_change_calls = Qnil;
2407 DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks,
2408 doc: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2409 This affects `before-change-functions' and `after-change-functions',
2410 as well as hooks attached to text properties and overlays. */);
2411 inhibit_modification_hooks = 0;
2412 Qinhibit_modification_hooks = intern_c_string ("inhibit-modification-hooks");
2413 staticpro (&Qinhibit_modification_hooks);
2415 defsubr (&Scombine_after_change_execute);
2418 /* arch-tag: 9b34b886-47d7-465e-a234-299af411b23d
2419 (do not change this comment) */