* keyboard.c (parse_modifiers_uncached, parse_modifiers):
[emacs.git] / src / insdel.c
blob4bdcb4bc0b731fc9c9ffd030664cde368ab090c5
1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985-1986, 1993-1995, 1997-2011
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 #include <config.h>
22 #include <setjmp.h>
23 #include "lisp.h"
24 #include "intervals.h"
25 #include "buffer.h"
26 #include "character.h"
27 #include "window.h"
28 #include "blockinput.h"
29 #include "region-cache.h"
31 #ifndef NULL
32 #define NULL 0
33 #endif
35 static void insert_from_string_1 (Lisp_Object string,
36 EMACS_INT pos, EMACS_INT pos_byte,
37 EMACS_INT nchars, EMACS_INT nbytes,
38 int inherit, int before_markers);
39 static void insert_from_buffer_1 (struct buffer *buf,
40 EMACS_INT from, EMACS_INT nchars,
41 int inherit);
42 static void gap_left (EMACS_INT charpos, EMACS_INT bytepos, int newgap);
43 static void gap_right (EMACS_INT charpos, EMACS_INT bytepos);
44 static void adjust_markers_for_insert (EMACS_INT from, EMACS_INT from_byte,
45 EMACS_INT to, EMACS_INT to_byte,
46 int before_markers);
47 static void adjust_markers_for_replace (EMACS_INT, EMACS_INT, EMACS_INT,
48 EMACS_INT, EMACS_INT, EMACS_INT);
49 static void adjust_point (EMACS_INT nchars, EMACS_INT nbytes);
51 Lisp_Object Fcombine_after_change_execute (void);
53 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
54 describing changes which happened while combine_after_change_calls
55 was nonzero. We use this to decide how to call them
56 once the deferral ends.
58 In each element.
59 BEG-UNCHANGED is the number of chars before the changed range.
60 END-UNCHANGED is the number of chars after the changed range,
61 and CHANGE-AMOUNT is the number of characters inserted by the change
62 (negative for a deletion). */
63 Lisp_Object combine_after_change_list;
65 /* Buffer which combine_after_change_list is about. */
66 Lisp_Object combine_after_change_buffer;
68 Lisp_Object Qinhibit_modification_hooks;
70 #define CHECK_MARKERS() \
71 do \
72 { \
73 if (check_markers_debug_flag) \
74 check_markers (); \
75 } \
76 while (0)
78 static void
79 check_markers (void)
81 register struct Lisp_Marker *tail;
82 int multibyte = ! NILP (BVAR (current_buffer, enable_multibyte_characters));
84 for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
86 if (tail->buffer->text != current_buffer->text)
87 abort ();
88 if (tail->charpos > Z)
89 abort ();
90 if (tail->bytepos > Z_BYTE)
91 abort ();
92 if (multibyte && ! CHAR_HEAD_P (FETCH_BYTE (tail->bytepos)))
93 abort ();
97 /* Move gap to position CHARPOS.
98 Note that this can quit! */
100 void
101 move_gap (EMACS_INT charpos)
103 move_gap_both (charpos, charpos_to_bytepos (charpos));
106 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
107 Note that this can quit! */
109 void
110 move_gap_both (EMACS_INT charpos, EMACS_INT bytepos)
112 if (bytepos < GPT_BYTE)
113 gap_left (charpos, bytepos, 0);
114 else if (bytepos > GPT_BYTE)
115 gap_right (charpos, bytepos);
118 /* Move the gap to a position less than the current GPT.
119 BYTEPOS describes the new position as a byte position,
120 and CHARPOS is the corresponding char position.
121 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
123 static void
124 gap_left (EMACS_INT charpos, EMACS_INT bytepos, int newgap)
126 register unsigned char *to, *from;
127 register EMACS_INT i;
128 EMACS_INT new_s1;
130 if (!newgap)
131 BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
133 i = GPT_BYTE;
134 to = GAP_END_ADDR;
135 from = GPT_ADDR;
136 new_s1 = GPT_BYTE;
138 /* Now copy the characters. To move the gap down,
139 copy characters up. */
141 while (1)
143 /* I gets number of characters left to copy. */
144 i = new_s1 - bytepos;
145 if (i == 0)
146 break;
147 /* If a quit is requested, stop copying now.
148 Change BYTEPOS to be where we have actually moved the gap to. */
149 if (QUITP)
151 bytepos = new_s1;
152 charpos = BYTE_TO_CHAR (bytepos);
153 break;
155 /* Move at most 32000 chars before checking again for a quit. */
156 if (i > 32000)
157 i = 32000;
158 new_s1 -= i;
159 from -= i, to -= i;
160 memmove (to, from, i);
163 /* Adjust buffer data structure, to put the gap at BYTEPOS.
164 BYTEPOS is where the loop above stopped, which may be what
165 was specified or may be where a quit was detected. */
166 GPT_BYTE = bytepos;
167 GPT = charpos;
168 if (bytepos < charpos)
169 abort ();
170 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
171 QUIT;
174 /* Move the gap to a position greater than the current GPT.
175 BYTEPOS describes the new position as a byte position,
176 and CHARPOS is the corresponding char position. */
178 static void
179 gap_right (EMACS_INT charpos, EMACS_INT bytepos)
181 register unsigned char *to, *from;
182 register EMACS_INT i;
183 EMACS_INT new_s1;
185 BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
187 i = GPT_BYTE;
188 from = GAP_END_ADDR;
189 to = GPT_ADDR;
190 new_s1 = GPT_BYTE;
192 /* Now copy the characters. To move the gap up,
193 copy characters down. */
195 while (1)
197 /* I gets number of characters left to copy. */
198 i = bytepos - new_s1;
199 if (i == 0)
200 break;
201 /* If a quit is requested, stop copying now.
202 Change BYTEPOS to be where we have actually moved the gap to. */
203 if (QUITP)
205 bytepos = new_s1;
206 charpos = BYTE_TO_CHAR (bytepos);
207 break;
209 /* Move at most 32000 chars before checking again for a quit. */
210 if (i > 32000)
211 i = 32000;
212 new_s1 += i;
213 memmove (to, from, i);
214 from += i, to += i;
217 GPT = charpos;
218 GPT_BYTE = bytepos;
219 if (bytepos < charpos)
220 abort ();
221 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
222 QUIT;
225 /* Adjust all markers for a deletion
226 whose range in bytes is FROM_BYTE to TO_BYTE.
227 The range in charpos is FROM to TO.
229 This function assumes that the gap is adjacent to
230 or inside of the range being deleted. */
232 void
233 adjust_markers_for_delete (EMACS_INT from, EMACS_INT from_byte,
234 EMACS_INT to, EMACS_INT to_byte)
236 Lisp_Object marker;
237 register struct Lisp_Marker *m;
238 register EMACS_INT charpos;
240 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
242 charpos = m->charpos;
244 if (charpos > Z)
245 abort ();
247 /* If the marker is after the deletion,
248 relocate by number of chars / bytes deleted. */
249 if (charpos > to)
251 m->charpos -= to - from;
252 m->bytepos -= to_byte - from_byte;
254 /* Here's the case where a marker is inside text being deleted. */
255 else if (charpos > from)
257 if (! m->insertion_type)
258 { /* Normal markers will end up at the beginning of the
259 re-inserted text after undoing a deletion, and must be
260 adjusted to move them to the correct place. */
261 XSETMISC (marker, m);
262 record_marker_adjustment (marker, from - charpos);
264 else if (charpos < to)
265 { /* Before-insertion markers will automatically move forward
266 upon re-inserting the deleted text, so we have to arrange
267 for them to move backward to the correct position. */
268 XSETMISC (marker, m);
269 record_marker_adjustment (marker, to - charpos);
271 m->charpos = from;
272 m->bytepos = from_byte;
274 /* Here's the case where a before-insertion marker is immediately
275 before the deleted region. */
276 else if (charpos == from && m->insertion_type)
278 /* Undoing the change uses normal insertion, which will
279 incorrectly make MARKER move forward, so we arrange for it
280 to then move backward to the correct place at the beginning
281 of the deleted region. */
282 XSETMISC (marker, m);
283 record_marker_adjustment (marker, to - from);
289 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
290 to TO / TO_BYTE. We have to relocate the charpos of every marker
291 that points after the insertion (but not their bytepos).
293 When a marker points at the insertion point,
294 we advance it if either its insertion-type is t
295 or BEFORE_MARKERS is true. */
297 static void
298 adjust_markers_for_insert (EMACS_INT from, EMACS_INT from_byte,
299 EMACS_INT to, EMACS_INT to_byte, int before_markers)
301 struct Lisp_Marker *m;
302 int adjusted = 0;
303 EMACS_INT nchars = to - from;
304 EMACS_INT nbytes = to_byte - from_byte;
306 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
308 eassert (m->bytepos >= m->charpos
309 && m->bytepos - m->charpos <= Z_BYTE - Z);
311 if (m->bytepos == from_byte)
313 if (m->insertion_type || before_markers)
315 m->bytepos = to_byte;
316 m->charpos = to;
317 if (m->insertion_type)
318 adjusted = 1;
321 else if (m->bytepos > from_byte)
323 m->bytepos += nbytes;
324 m->charpos += nchars;
328 /* Adjusting only markers whose insertion-type is t may result in
329 - disordered start and end in overlays, and
330 - disordered overlays in the slot `overlays_before' of current_buffer. */
331 if (adjusted)
333 fix_start_end_in_overlays(from, to);
334 fix_overlays_before (current_buffer, from, to);
338 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
340 This is used only when the value of point changes due to an insert
341 or delete; it does not represent a conceptual change in point as a
342 marker. In particular, point is not crossing any interval
343 boundaries, so there's no need to use the usual SET_PT macro. In
344 fact it would be incorrect to do so, because either the old or the
345 new value of point is out of sync with the current set of
346 intervals. */
348 static void
349 adjust_point (EMACS_INT nchars, EMACS_INT nbytes)
351 SET_BUF_PT_BOTH (current_buffer, PT + nchars, PT_BYTE + nbytes);
352 /* In a single-byte buffer, the two positions must be equal. */
353 eassert (PT_BYTE >= PT && PT_BYTE - PT <= ZV_BYTE - ZV);
356 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
357 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
358 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
359 an insertion. */
361 static void
362 adjust_markers_for_replace (EMACS_INT from, EMACS_INT from_byte,
363 EMACS_INT old_chars, EMACS_INT old_bytes,
364 EMACS_INT new_chars, EMACS_INT new_bytes)
366 register struct Lisp_Marker *m;
367 EMACS_INT prev_to_byte = from_byte + old_bytes;
368 EMACS_INT diff_chars = new_chars - old_chars;
369 EMACS_INT diff_bytes = new_bytes - old_bytes;
371 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
373 if (m->bytepos >= prev_to_byte)
375 m->charpos += diff_chars;
376 m->bytepos += diff_bytes;
378 else if (m->bytepos > from_byte)
380 m->charpos = from;
381 m->bytepos = from_byte;
385 CHECK_MARKERS ();
389 /* Make the gap NBYTES_ADDED bytes longer. */
391 static void
392 make_gap_larger (EMACS_INT nbytes_added)
394 Lisp_Object tem;
395 EMACS_INT real_gap_loc;
396 EMACS_INT real_gap_loc_byte;
397 EMACS_INT old_gap_size;
399 /* If we have to get more space, get enough to last a while. */
400 nbytes_added += 2000;
402 { EMACS_INT total_size = Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added;
403 if (total_size < 0
404 /* Don't allow a buffer size that won't fit in a Lisp integer. */
405 || total_size != XINT (make_number (total_size))
406 /* Don't allow a buffer size that won't fit in an int
407 even if it will fit in a Lisp integer.
408 That won't work because so many places still use `int'. */
409 || total_size != (EMACS_INT) (int) total_size)
410 error ("Buffer exceeds maximum size");
413 enlarge_buffer_text (current_buffer, nbytes_added);
415 /* Prevent quitting in move_gap. */
416 tem = Vinhibit_quit;
417 Vinhibit_quit = Qt;
419 real_gap_loc = GPT;
420 real_gap_loc_byte = GPT_BYTE;
421 old_gap_size = GAP_SIZE;
423 /* Call the newly allocated space a gap at the end of the whole space. */
424 GPT = Z + GAP_SIZE;
425 GPT_BYTE = Z_BYTE + GAP_SIZE;
426 GAP_SIZE = nbytes_added;
428 /* Move the new gap down to be consecutive with the end of the old one.
429 This adjusts the markers properly too. */
430 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
432 /* Now combine the two into one large gap. */
433 GAP_SIZE += old_gap_size;
434 GPT = real_gap_loc;
435 GPT_BYTE = real_gap_loc_byte;
437 /* Put an anchor. */
438 *(Z_ADDR) = 0;
440 Vinhibit_quit = tem;
444 /* Make the gap NBYTES_REMOVED bytes shorter. */
446 static void
447 make_gap_smaller (EMACS_INT nbytes_removed)
449 Lisp_Object tem;
450 EMACS_INT real_gap_loc;
451 EMACS_INT real_gap_loc_byte;
452 EMACS_INT real_Z;
453 EMACS_INT real_Z_byte;
454 EMACS_INT real_beg_unchanged;
455 EMACS_INT new_gap_size;
457 /* Make sure the gap is at least 20 bytes. */
458 if (GAP_SIZE - nbytes_removed < 20)
459 nbytes_removed = GAP_SIZE - 20;
461 /* Prevent quitting in move_gap. */
462 tem = Vinhibit_quit;
463 Vinhibit_quit = Qt;
465 real_gap_loc = GPT;
466 real_gap_loc_byte = GPT_BYTE;
467 new_gap_size = GAP_SIZE - nbytes_removed;
468 real_Z = Z;
469 real_Z_byte = Z_BYTE;
470 real_beg_unchanged = BEG_UNCHANGED;
472 /* Pretend that the last unwanted part of the gap is the entire gap,
473 and that the first desired part of the gap is part of the buffer
474 text. */
475 memset (GPT_ADDR, 0, new_gap_size);
476 GPT += new_gap_size;
477 GPT_BYTE += new_gap_size;
478 Z += new_gap_size;
479 Z_BYTE += new_gap_size;
480 GAP_SIZE = nbytes_removed;
482 /* Move the unwanted pretend gap to the end of the buffer. This
483 adjusts the markers properly too. */
484 gap_right (Z, Z_BYTE);
486 enlarge_buffer_text (current_buffer, -nbytes_removed);
488 /* Now restore the desired gap. */
489 GAP_SIZE = new_gap_size;
490 GPT = real_gap_loc;
491 GPT_BYTE = real_gap_loc_byte;
492 Z = real_Z;
493 Z_BYTE = real_Z_byte;
494 BEG_UNCHANGED = real_beg_unchanged;
496 /* Put an anchor. */
497 *(Z_ADDR) = 0;
499 Vinhibit_quit = tem;
502 void
503 make_gap (EMACS_INT nbytes_added)
505 if (nbytes_added >= 0)
506 make_gap_larger (nbytes_added);
507 #if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
508 else
509 make_gap_smaller (-nbytes_added);
510 #endif
513 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
514 FROM_MULTIBYTE says whether the incoming text is multibyte.
515 TO_MULTIBYTE says whether to store the text as multibyte.
516 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
518 Return the number of bytes stored at TO_ADDR. */
520 EMACS_INT
521 copy_text (const unsigned char *from_addr, unsigned char *to_addr,
522 EMACS_INT nbytes, int from_multibyte, int to_multibyte)
524 if (from_multibyte == to_multibyte)
526 memcpy (to_addr, from_addr, nbytes);
527 return nbytes;
529 else if (from_multibyte)
531 EMACS_INT nchars = 0;
532 EMACS_INT bytes_left = nbytes;
534 while (bytes_left > 0)
536 int thislen, c;
537 c = STRING_CHAR_AND_LENGTH (from_addr, thislen);
538 if (! ASCII_CHAR_P (c))
539 c &= 0xFF;
540 *to_addr++ = c;
541 from_addr += thislen;
542 bytes_left -= thislen;
543 nchars++;
545 return nchars;
547 else
549 unsigned char *initial_to_addr = to_addr;
551 /* Convert single-byte to multibyte. */
552 while (nbytes > 0)
554 int c = *from_addr++;
556 if (!ASCII_CHAR_P (c))
558 c = BYTE8_TO_CHAR (c);
559 to_addr += CHAR_STRING (c, to_addr);
560 nbytes--;
562 else
563 /* Special case for speed. */
564 *to_addr++ = c, nbytes--;
566 return to_addr - initial_to_addr;
570 /* Return the number of bytes it would take
571 to convert some single-byte text to multibyte.
572 The single-byte text consists of NBYTES bytes at PTR. */
574 EMACS_INT
575 count_size_as_multibyte (const unsigned char *ptr, EMACS_INT nbytes)
577 EMACS_INT i;
578 EMACS_INT outgoing_nbytes = 0;
580 for (i = 0; i < nbytes; i++)
582 unsigned int c = *ptr++;
584 if (ASCII_CHAR_P (c))
585 outgoing_nbytes++;
586 else
588 c = BYTE8_TO_CHAR (c);
589 outgoing_nbytes += CHAR_BYTES (c);
593 return outgoing_nbytes;
596 /* Insert a string of specified length before point.
597 This function judges multibyteness based on
598 enable_multibyte_characters in the current buffer;
599 it never converts between single-byte and multibyte.
601 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
602 prepare_to_modify_buffer could relocate the text. */
604 void
605 insert (const char *string, EMACS_INT nbytes)
607 if (nbytes > 0)
609 EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
610 insert_1_both (string, len, nbytes, 0, 1, 0);
611 opoint = PT - len;
612 signal_after_change (opoint, 0, len);
613 update_compositions (opoint, PT, CHECK_BORDER);
617 /* Likewise, but inherit text properties from neighboring characters. */
619 void
620 insert_and_inherit (const char *string, EMACS_INT nbytes)
622 if (nbytes > 0)
624 EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
625 insert_1_both (string, len, nbytes, 1, 1, 0);
626 opoint = PT - len;
627 signal_after_change (opoint, 0, len);
628 update_compositions (opoint, PT, CHECK_BORDER);
632 /* Insert the character C before point. Do not inherit text properties. */
634 void
635 insert_char (int c)
637 unsigned char str[MAX_MULTIBYTE_LENGTH];
638 int len;
640 if (! NILP (BVAR (current_buffer, enable_multibyte_characters)))
641 len = CHAR_STRING (c, str);
642 else
644 len = 1;
645 str[0] = c;
648 insert ((char *) str, len);
651 /* Insert the null-terminated string S before point. */
653 void
654 insert_string (const char *s)
656 insert (s, strlen (s));
659 /* Like `insert' except that all markers pointing at the place where
660 the insertion happens are adjusted to point after it.
661 Don't use this function to insert part of a Lisp string,
662 since gc could happen and relocate it. */
664 void
665 insert_before_markers (const char *string, EMACS_INT nbytes)
667 if (nbytes > 0)
669 EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
670 insert_1_both (string, len, nbytes, 0, 1, 1);
671 opoint = PT - len;
672 signal_after_change (opoint, 0, len);
673 update_compositions (opoint, PT, CHECK_BORDER);
677 /* Likewise, but inherit text properties from neighboring characters. */
679 void
680 insert_before_markers_and_inherit (const char *string,
681 EMACS_INT nbytes)
683 if (nbytes > 0)
685 EMACS_INT len = chars_in_text ((unsigned char *) string, nbytes), opoint;
686 insert_1_both (string, len, nbytes, 1, 1, 1);
687 opoint = PT - len;
688 signal_after_change (opoint, 0, len);
689 update_compositions (opoint, PT, CHECK_BORDER);
693 /* Subroutine used by the insert functions above. */
695 void
696 insert_1 (const char *string, EMACS_INT nbytes,
697 int inherit, int prepare, int before_markers)
699 insert_1_both (string, chars_in_text ((unsigned char *) string, nbytes),
700 nbytes, inherit, prepare, before_markers);
704 #ifdef BYTE_COMBINING_DEBUG
706 /* See if the bytes before POS/POS_BYTE combine with bytes
707 at the start of STRING to form a single character.
708 If so, return the number of bytes at the start of STRING
709 which combine in this way. Otherwise, return 0. */
712 count_combining_before (const unsigned char *string, EMACS_INT length,
713 EMACS_INT pos, EMACS_INT pos_byte)
715 int len, combining_bytes;
716 const unsigned char *p;
718 if (NILP (current_buffer->enable_multibyte_characters))
719 return 0;
721 /* At first, we can exclude the following cases:
722 (1) STRING[0] can't be a following byte of multibyte sequence.
723 (2) POS is the start of the current buffer.
724 (3) A character before POS is not a multibyte character. */
725 if (length == 0 || CHAR_HEAD_P (*string)) /* case (1) */
726 return 0;
727 if (pos_byte == BEG_BYTE) /* case (2) */
728 return 0;
729 len = 1;
730 p = BYTE_POS_ADDR (pos_byte - 1);
731 while (! CHAR_HEAD_P (*p)) p--, len++;
732 if (! LEADING_CODE_P (*p)) /* case (3) */
733 return 0;
735 combining_bytes = BYTES_BY_CHAR_HEAD (*p) - len;
736 if (combining_bytes <= 0)
737 /* The character preceding POS is, complete and no room for
738 combining bytes (combining_bytes == 0), or an independent 8-bit
739 character (combining_bytes < 0). */
740 return 0;
742 /* We have a combination situation. Count the bytes at STRING that
743 may combine. */
744 p = string + 1;
745 while (!CHAR_HEAD_P (*p) && p < string + length)
746 p++;
748 return (combining_bytes < p - string ? combining_bytes : p - string);
751 /* See if the bytes after POS/POS_BYTE combine with bytes
752 at the end of STRING to form a single character.
753 If so, return the number of bytes after POS/POS_BYTE
754 which combine in this way. Otherwise, return 0. */
757 count_combining_after (const unsigned char *string,
758 EMACS_INT length, EMACS_INT pos, EMACS_INT pos_byte)
760 EMACS_INT opos_byte = pos_byte;
761 EMACS_INT i;
762 EMACS_INT bytes;
763 unsigned char *bufp;
765 if (NILP (current_buffer->enable_multibyte_characters))
766 return 0;
768 /* At first, we can exclude the following cases:
769 (1) The last byte of STRING is an ASCII.
770 (2) POS is the last of the current buffer.
771 (3) A character at POS can't be a following byte of multibyte
772 character. */
773 if (length > 0 && ASCII_BYTE_P (string[length - 1])) /* case (1) */
774 return 0;
775 if (pos_byte == Z_BYTE) /* case (2) */
776 return 0;
777 bufp = BYTE_POS_ADDR (pos_byte);
778 if (CHAR_HEAD_P (*bufp)) /* case (3) */
779 return 0;
781 i = length - 1;
782 while (i >= 0 && ! CHAR_HEAD_P (string[i]))
784 i--;
786 if (i < 0)
788 /* All characters in STRING are not character head. We must
789 check also preceding bytes at POS. We are sure that the gap
790 is at POS. */
791 unsigned char *p = BEG_ADDR;
792 i = pos_byte - 2;
793 while (i >= 0 && ! CHAR_HEAD_P (p[i]))
794 i--;
795 if (i < 0 || !LEADING_CODE_P (p[i]))
796 return 0;
798 bytes = BYTES_BY_CHAR_HEAD (p[i]);
799 return (bytes <= pos_byte - 1 - i + length
801 : bytes - (pos_byte - 1 - i + length));
803 if (!LEADING_CODE_P (string[i]))
804 return 0;
806 bytes = BYTES_BY_CHAR_HEAD (string[i]) - (length - i);
807 bufp++, pos_byte++;
808 while (!CHAR_HEAD_P (*bufp)) bufp++, pos_byte++;
810 return (bytes <= pos_byte - opos_byte ? bytes : pos_byte - opos_byte);
813 #endif
816 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
817 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
818 are the same as in insert_1. */
820 void
821 insert_1_both (const char *string,
822 EMACS_INT nchars, EMACS_INT nbytes,
823 int inherit, int prepare, int before_markers)
825 if (nchars == 0)
826 return;
828 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
829 nchars = nbytes;
831 if (prepare)
832 /* Do this before moving and increasing the gap,
833 because the before-change hooks might move the gap
834 or make it smaller. */
835 prepare_to_modify_buffer (PT, PT, NULL);
837 if (PT != GPT)
838 move_gap_both (PT, PT_BYTE);
839 if (GAP_SIZE < nbytes)
840 make_gap (nbytes - GAP_SIZE);
842 #ifdef BYTE_COMBINING_DEBUG
843 if (count_combining_before (string, nbytes, PT, PT_BYTE)
844 || count_combining_after (string, nbytes, PT, PT_BYTE))
845 abort ();
846 #endif
848 /* Record deletion of the surrounding text that combines with
849 the insertion. This, together with recording the insertion,
850 will add up to the right stuff in the undo list. */
851 record_insert (PT, nchars);
852 MODIFF++;
853 CHARS_MODIFF = MODIFF;
855 memcpy (GPT_ADDR, string, nbytes);
857 GAP_SIZE -= nbytes;
858 GPT += nchars;
859 ZV += nchars;
860 Z += nchars;
861 GPT_BYTE += nbytes;
862 ZV_BYTE += nbytes;
863 Z_BYTE += nbytes;
864 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
866 if (GPT_BYTE < GPT)
867 abort ();
869 /* The insert may have been in the unchanged region, so check again. */
870 if (Z - GPT < END_UNCHANGED)
871 END_UNCHANGED = Z - GPT;
873 adjust_overlays_for_insert (PT, nchars);
874 adjust_markers_for_insert (PT, PT_BYTE,
875 PT + nchars, PT_BYTE + nbytes,
876 before_markers);
878 if (BUF_INTERVALS (current_buffer) != 0)
879 offset_intervals (current_buffer, PT, nchars);
881 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
882 set_text_properties (make_number (PT), make_number (PT + nchars),
883 Qnil, Qnil, Qnil);
885 adjust_point (nchars, nbytes);
887 CHECK_MARKERS ();
890 /* Insert the part of the text of STRING, a Lisp object assumed to be
891 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
892 starting at position POS / POS_BYTE. If the text of STRING has properties,
893 copy them into the buffer.
895 It does not work to use `insert' for this, because a GC could happen
896 before we copy the stuff into the buffer, and relocate the string
897 without insert noticing. */
899 void
900 insert_from_string (Lisp_Object string, EMACS_INT pos, EMACS_INT pos_byte,
901 EMACS_INT length, EMACS_INT length_byte, int inherit)
903 EMACS_INT opoint = PT;
905 if (SCHARS (string) == 0)
906 return;
908 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
909 inherit, 0);
910 signal_after_change (opoint, 0, PT - opoint);
911 update_compositions (opoint, PT, CHECK_BORDER);
914 /* Like `insert_from_string' except that all markers pointing
915 at the place where the insertion happens are adjusted to point after it. */
917 void
918 insert_from_string_before_markers (Lisp_Object string,
919 EMACS_INT pos, EMACS_INT pos_byte,
920 EMACS_INT length, EMACS_INT length_byte,
921 int inherit)
923 EMACS_INT opoint = PT;
925 if (SCHARS (string) == 0)
926 return;
928 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
929 inherit, 1);
930 signal_after_change (opoint, 0, PT - opoint);
931 update_compositions (opoint, PT, CHECK_BORDER);
934 /* Subroutine of the insertion functions above. */
936 static void
937 insert_from_string_1 (Lisp_Object string, EMACS_INT pos, EMACS_INT pos_byte,
938 EMACS_INT nchars, EMACS_INT nbytes,
939 int inherit, int before_markers)
941 struct gcpro gcpro1;
942 EMACS_INT outgoing_nbytes = nbytes;
943 INTERVAL intervals;
945 /* Make OUTGOING_NBYTES describe the text
946 as it will be inserted in this buffer. */
948 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
949 outgoing_nbytes = nchars;
950 else if (! STRING_MULTIBYTE (string))
951 outgoing_nbytes
952 = count_size_as_multibyte (SDATA (string) + pos_byte,
953 nbytes);
955 GCPRO1 (string);
956 /* Do this before moving and increasing the gap,
957 because the before-change hooks might move the gap
958 or make it smaller. */
959 prepare_to_modify_buffer (PT, PT, NULL);
961 if (PT != GPT)
962 move_gap_both (PT, PT_BYTE);
963 if (GAP_SIZE < outgoing_nbytes)
964 make_gap (outgoing_nbytes - GAP_SIZE);
965 UNGCPRO;
967 /* Copy the string text into the buffer, perhaps converting
968 between single-byte and multibyte. */
969 copy_text (SDATA (string) + pos_byte, GPT_ADDR, nbytes,
970 STRING_MULTIBYTE (string),
971 ! NILP (BVAR (current_buffer, enable_multibyte_characters)));
973 #ifdef BYTE_COMBINING_DEBUG
974 /* We have copied text into the gap, but we have not altered
975 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
976 to these functions and get the same results as we would
977 have got earlier on. Meanwhile, PT_ADDR does point to
978 the text that has been stored by copy_text. */
979 if (count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE)
980 || count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE))
981 abort ();
982 #endif
984 record_insert (PT, nchars);
985 MODIFF++;
986 CHARS_MODIFF = MODIFF;
988 GAP_SIZE -= outgoing_nbytes;
989 GPT += nchars;
990 ZV += nchars;
991 Z += nchars;
992 GPT_BYTE += outgoing_nbytes;
993 ZV_BYTE += outgoing_nbytes;
994 Z_BYTE += outgoing_nbytes;
995 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
997 if (GPT_BYTE < GPT)
998 abort ();
1000 /* The insert may have been in the unchanged region, so check again. */
1001 if (Z - GPT < END_UNCHANGED)
1002 END_UNCHANGED = Z - GPT;
1004 adjust_overlays_for_insert (PT, nchars);
1005 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1006 PT_BYTE + outgoing_nbytes,
1007 before_markers);
1009 offset_intervals (current_buffer, PT, nchars);
1011 intervals = STRING_INTERVALS (string);
1012 /* Get the intervals for the part of the string we are inserting. */
1013 if (nbytes < SBYTES (string))
1014 intervals = copy_intervals (intervals, pos, nchars);
1016 /* Insert those intervals. */
1017 graft_intervals_into_buffer (intervals, PT, nchars,
1018 current_buffer, inherit);
1020 adjust_point (nchars, outgoing_nbytes);
1022 CHECK_MARKERS ();
1025 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1026 starting at GPT_ADDR. */
1028 void
1029 insert_from_gap (EMACS_INT nchars, EMACS_INT nbytes)
1031 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
1032 nchars = nbytes;
1034 record_insert (GPT, nchars);
1035 MODIFF++;
1037 GAP_SIZE -= nbytes;
1038 GPT += nchars;
1039 ZV += nchars;
1040 Z += nchars;
1041 GPT_BYTE += nbytes;
1042 ZV_BYTE += nbytes;
1043 Z_BYTE += nbytes;
1044 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1046 if (GPT_BYTE < GPT)
1047 abort ();
1049 adjust_overlays_for_insert (GPT - nchars, nchars);
1050 adjust_markers_for_insert (GPT - nchars, GPT_BYTE - nbytes,
1051 GPT, GPT_BYTE, 0);
1053 if (BUF_INTERVALS (current_buffer) != 0)
1055 offset_intervals (current_buffer, GPT - nchars, nchars);
1056 graft_intervals_into_buffer (NULL_INTERVAL, GPT - nchars, nchars,
1057 current_buffer, 0);
1060 if (GPT - nchars < PT)
1061 adjust_point (nchars, nbytes);
1063 CHECK_MARKERS ();
1066 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1067 current buffer. If the text in BUF has properties, they are absorbed
1068 into the current buffer.
1070 It does not work to use `insert' for this, because a malloc could happen
1071 and relocate BUF's text before the copy happens. */
1073 void
1074 insert_from_buffer (struct buffer *buf,
1075 EMACS_INT charpos, EMACS_INT nchars, int inherit)
1077 EMACS_INT opoint = PT;
1079 insert_from_buffer_1 (buf, charpos, nchars, inherit);
1080 signal_after_change (opoint, 0, PT - opoint);
1081 update_compositions (opoint, PT, CHECK_BORDER);
1084 static void
1085 insert_from_buffer_1 (struct buffer *buf,
1086 EMACS_INT from, EMACS_INT nchars, int inherit)
1088 register Lisp_Object temp;
1089 EMACS_INT chunk, chunk_expanded;
1090 EMACS_INT from_byte = buf_charpos_to_bytepos (buf, from);
1091 EMACS_INT to_byte = buf_charpos_to_bytepos (buf, from + nchars);
1092 EMACS_INT incoming_nbytes = to_byte - from_byte;
1093 EMACS_INT outgoing_nbytes = incoming_nbytes;
1094 INTERVAL intervals;
1096 /* Make OUTGOING_NBYTES describe the text
1097 as it will be inserted in this buffer. */
1099 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
1100 outgoing_nbytes = nchars;
1101 else if (NILP (BVAR (buf, enable_multibyte_characters)))
1103 EMACS_INT outgoing_before_gap = 0;
1104 EMACS_INT outgoing_after_gap = 0;
1106 if (from < BUF_GPT (buf))
1108 chunk = BUF_GPT_BYTE (buf) - from_byte;
1109 if (chunk > incoming_nbytes)
1110 chunk = incoming_nbytes;
1111 outgoing_before_gap
1112 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf, from_byte),
1113 chunk);
1115 else
1116 chunk = 0;
1118 if (chunk < incoming_nbytes)
1119 outgoing_after_gap
1120 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf,
1121 from_byte + chunk),
1122 incoming_nbytes - chunk);
1124 outgoing_nbytes = outgoing_before_gap + outgoing_after_gap;
1127 /* Make sure point-max won't overflow after this insertion. */
1128 XSETINT (temp, outgoing_nbytes + Z);
1129 if (outgoing_nbytes + Z != XINT (temp))
1130 error ("Maximum buffer size exceeded");
1132 /* Do this before moving and increasing the gap,
1133 because the before-change hooks might move the gap
1134 or make it smaller. */
1135 prepare_to_modify_buffer (PT, PT, NULL);
1137 if (PT != GPT)
1138 move_gap_both (PT, PT_BYTE);
1139 if (GAP_SIZE < outgoing_nbytes)
1140 make_gap (outgoing_nbytes - GAP_SIZE);
1142 if (from < BUF_GPT (buf))
1144 chunk = BUF_GPT_BYTE (buf) - from_byte;
1145 if (chunk > incoming_nbytes)
1146 chunk = incoming_nbytes;
1147 /* Record number of output bytes, so we know where
1148 to put the output from the second copy_text. */
1149 chunk_expanded
1150 = copy_text (BUF_BYTE_ADDRESS (buf, from_byte),
1151 GPT_ADDR, chunk,
1152 ! NILP (BVAR (buf, enable_multibyte_characters)),
1153 ! NILP (BVAR (current_buffer, enable_multibyte_characters)));
1155 else
1156 chunk_expanded = chunk = 0;
1158 if (chunk < incoming_nbytes)
1159 copy_text (BUF_BYTE_ADDRESS (buf, from_byte + chunk),
1160 GPT_ADDR + chunk_expanded, incoming_nbytes - chunk,
1161 ! NILP (BVAR (buf, enable_multibyte_characters)),
1162 ! NILP (BVAR (current_buffer, enable_multibyte_characters)));
1164 #ifdef BYTE_COMBINING_DEBUG
1165 /* We have copied text into the gap, but we have not altered
1166 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1167 to these functions and get the same results as we would
1168 have got earlier on. Meanwhile, GPT_ADDR does point to
1169 the text that has been stored by copy_text. */
1170 if (count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE)
1171 || count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE))
1172 abort ();
1173 #endif
1175 record_insert (PT, nchars);
1176 MODIFF++;
1177 CHARS_MODIFF = MODIFF;
1179 GAP_SIZE -= outgoing_nbytes;
1180 GPT += nchars;
1181 ZV += nchars;
1182 Z += nchars;
1183 GPT_BYTE += outgoing_nbytes;
1184 ZV_BYTE += outgoing_nbytes;
1185 Z_BYTE += outgoing_nbytes;
1186 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1188 if (GPT_BYTE < GPT)
1189 abort ();
1191 /* The insert may have been in the unchanged region, so check again. */
1192 if (Z - GPT < END_UNCHANGED)
1193 END_UNCHANGED = Z - GPT;
1195 adjust_overlays_for_insert (PT, nchars);
1196 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1197 PT_BYTE + outgoing_nbytes,
1200 if (BUF_INTERVALS (current_buffer) != 0)
1201 offset_intervals (current_buffer, PT, nchars);
1203 /* Get the intervals for the part of the string we are inserting. */
1204 intervals = BUF_INTERVALS (buf);
1205 if (nchars < BUF_Z (buf) - BUF_BEG (buf))
1207 if (buf == current_buffer && PT <= from)
1208 from += nchars;
1209 intervals = copy_intervals (intervals, from, nchars);
1212 /* Insert those intervals. */
1213 graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
1215 adjust_point (nchars, outgoing_nbytes);
1218 /* Record undo information and adjust markers and position keepers for
1219 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1220 chars (LEN_BYTE bytes) which resides in the gap just after
1221 GPT_ADDR.
1223 PREV_TEXT nil means the new text was just inserted. */
1225 void
1226 adjust_after_replace (EMACS_INT from, EMACS_INT from_byte,
1227 Lisp_Object prev_text, EMACS_INT len, EMACS_INT len_byte)
1229 EMACS_INT nchars_del = 0, nbytes_del = 0;
1231 #ifdef BYTE_COMBINING_DEBUG
1232 if (count_combining_before (GPT_ADDR, len_byte, from, from_byte)
1233 || count_combining_after (GPT_ADDR, len_byte, from, from_byte))
1234 abort ();
1235 #endif
1237 if (STRINGP (prev_text))
1239 nchars_del = SCHARS (prev_text);
1240 nbytes_del = SBYTES (prev_text);
1243 /* Update various buffer positions for the new text. */
1244 GAP_SIZE -= len_byte;
1245 ZV += len; Z+= len;
1246 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1247 GPT += len; GPT_BYTE += len_byte;
1248 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1250 if (nchars_del > 0)
1251 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1252 len, len_byte);
1253 else
1254 adjust_markers_for_insert (from, from_byte,
1255 from + len, from_byte + len_byte, 0);
1257 if (! EQ (BVAR (current_buffer, undo_list), Qt))
1259 if (nchars_del > 0)
1260 record_delete (from, prev_text);
1261 record_insert (from, len);
1264 if (len > nchars_del)
1265 adjust_overlays_for_insert (from, len - nchars_del);
1266 else if (len < nchars_del)
1267 adjust_overlays_for_delete (from, nchars_del - len);
1268 if (BUF_INTERVALS (current_buffer) != 0)
1270 offset_intervals (current_buffer, from, len - nchars_del);
1273 if (from < PT)
1274 adjust_point (len - nchars_del, len_byte - nbytes_del);
1276 /* As byte combining will decrease Z, we must check this again. */
1277 if (Z - GPT < END_UNCHANGED)
1278 END_UNCHANGED = Z - GPT;
1280 CHECK_MARKERS ();
1282 if (len == 0)
1283 evaporate_overlays (from);
1284 MODIFF++;
1285 CHARS_MODIFF = MODIFF;
1288 /* Like adjust_after_replace, but doesn't require PREV_TEXT.
1289 This is for use when undo is not enabled in the current buffer. */
1291 void
1292 adjust_after_replace_noundo (EMACS_INT from, EMACS_INT from_byte,
1293 EMACS_INT nchars_del, EMACS_INT nbytes_del,
1294 EMACS_INT len, EMACS_INT len_byte)
1296 #ifdef BYTE_COMBINING_DEBUG
1297 if (count_combining_before (GPT_ADDR, len_byte, from, from_byte)
1298 || count_combining_after (GPT_ADDR, len_byte, from, from_byte))
1299 abort ();
1300 #endif
1302 /* Update various buffer positions for the new text. */
1303 GAP_SIZE -= len_byte;
1304 ZV += len; Z+= len;
1305 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1306 GPT += len; GPT_BYTE += len_byte;
1307 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1309 if (nchars_del > 0)
1310 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1311 len, len_byte);
1312 else
1313 adjust_markers_for_insert (from, from_byte,
1314 from + len, from_byte + len_byte, 0);
1316 if (len > nchars_del)
1317 adjust_overlays_for_insert (from, len - nchars_del);
1318 else if (len < nchars_del)
1319 adjust_overlays_for_delete (from, nchars_del - len);
1320 if (BUF_INTERVALS (current_buffer) != 0)
1322 offset_intervals (current_buffer, from, len - nchars_del);
1325 if (from < PT)
1326 adjust_point (len - nchars_del, len_byte - nbytes_del);
1328 /* As byte combining will decrease Z, we must check this again. */
1329 if (Z - GPT < END_UNCHANGED)
1330 END_UNCHANGED = Z - GPT;
1332 CHECK_MARKERS ();
1334 if (len == 0)
1335 evaporate_overlays (from);
1336 MODIFF++;
1337 CHARS_MODIFF = MODIFF;
1340 /* Record undo information, adjust markers and position keepers for an
1341 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1342 text already exists in the current buffer but character length (TO
1343 - FROM) may be incorrect, the correct length is NEWLEN. */
1345 void
1346 adjust_after_insert (EMACS_INT from, EMACS_INT from_byte,
1347 EMACS_INT to, EMACS_INT to_byte, EMACS_INT newlen)
1349 EMACS_INT len = to - from, len_byte = to_byte - from_byte;
1351 if (GPT != to)
1352 move_gap_both (to, to_byte);
1353 GAP_SIZE += len_byte;
1354 GPT -= len; GPT_BYTE -= len_byte;
1355 ZV -= len; ZV_BYTE -= len_byte;
1356 Z -= len; Z_BYTE -= len_byte;
1357 adjust_after_replace (from, from_byte, Qnil, newlen, len_byte);
1360 /* Replace the text from character positions FROM to TO with NEW,
1361 If PREPARE is nonzero, call prepare_to_modify_buffer.
1362 If INHERIT, the newly inserted text should inherit text properties
1363 from the surrounding non-deleted text. */
1365 /* Note that this does not yet handle markers quite right.
1366 Also it needs to record a single undo-entry that does a replacement
1367 rather than a separate delete and insert.
1368 That way, undo will also handle markers properly.
1370 But if MARKERS is 0, don't relocate markers. */
1372 void
1373 replace_range (EMACS_INT from, EMACS_INT to, Lisp_Object new,
1374 int prepare, int inherit, int markers)
1376 EMACS_INT inschars = SCHARS (new);
1377 EMACS_INT insbytes = SBYTES (new);
1378 EMACS_INT from_byte, to_byte;
1379 EMACS_INT nbytes_del, nchars_del;
1380 register Lisp_Object temp;
1381 struct gcpro gcpro1;
1382 INTERVAL intervals;
1383 EMACS_INT outgoing_insbytes = insbytes;
1384 Lisp_Object deletion;
1386 CHECK_MARKERS ();
1388 GCPRO1 (new);
1389 deletion = Qnil;
1391 if (prepare)
1393 EMACS_INT range_length = to - from;
1394 prepare_to_modify_buffer (from, to, &from);
1395 to = from + range_length;
1398 UNGCPRO;
1400 /* Make args be valid */
1401 if (from < BEGV)
1402 from = BEGV;
1403 if (to > ZV)
1404 to = ZV;
1406 from_byte = CHAR_TO_BYTE (from);
1407 to_byte = CHAR_TO_BYTE (to);
1409 nchars_del = to - from;
1410 nbytes_del = to_byte - from_byte;
1412 if (nbytes_del <= 0 && insbytes == 0)
1413 return;
1415 /* Make OUTGOING_INSBYTES describe the text
1416 as it will be inserted in this buffer. */
1418 if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
1419 outgoing_insbytes = inschars;
1420 else if (! STRING_MULTIBYTE (new))
1421 outgoing_insbytes
1422 = count_size_as_multibyte (SDATA (new), insbytes);
1424 /* Make sure point-max won't overflow after this insertion. */
1425 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1426 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1427 error ("Maximum buffer size exceeded");
1429 GCPRO1 (new);
1431 /* Make sure the gap is somewhere in or next to what we are deleting. */
1432 if (from > GPT)
1433 gap_right (from, from_byte);
1434 if (to < GPT)
1435 gap_left (to, to_byte, 0);
1437 /* Even if we don't record for undo, we must keep the original text
1438 because we may have to recover it because of inappropriate byte
1439 combining. */
1440 if (! EQ (BVAR (current_buffer, undo_list), Qt))
1441 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1443 GAP_SIZE += nbytes_del;
1444 ZV -= nchars_del;
1445 Z -= nchars_del;
1446 ZV_BYTE -= nbytes_del;
1447 Z_BYTE -= nbytes_del;
1448 GPT = from;
1449 GPT_BYTE = from_byte;
1450 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1452 if (GPT_BYTE < GPT)
1453 abort ();
1455 if (GPT - BEG < BEG_UNCHANGED)
1456 BEG_UNCHANGED = GPT - BEG;
1457 if (Z - GPT < END_UNCHANGED)
1458 END_UNCHANGED = Z - GPT;
1460 if (GAP_SIZE < insbytes)
1461 make_gap (insbytes - GAP_SIZE);
1463 /* Copy the string text into the buffer, perhaps converting
1464 between single-byte and multibyte. */
1465 copy_text (SDATA (new), GPT_ADDR, insbytes,
1466 STRING_MULTIBYTE (new),
1467 ! NILP (BVAR (current_buffer, enable_multibyte_characters)));
1469 #ifdef BYTE_COMBINING_DEBUG
1470 /* We have copied text into the gap, but we have not marked
1471 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1472 here, for both the previous text and the following text.
1473 Meanwhile, GPT_ADDR does point to
1474 the text that has been stored by copy_text. */
1475 if (count_combining_before (GPT_ADDR, outgoing_insbytes, from, from_byte)
1476 || count_combining_after (GPT_ADDR, outgoing_insbytes, from, from_byte))
1477 abort ();
1478 #endif
1480 if (! EQ (BVAR (current_buffer, undo_list), Qt))
1482 /* Record the insertion first, so that when we undo,
1483 the deletion will be undone first. Thus, undo
1484 will insert before deleting, and thus will keep
1485 the markers before and after this text separate. */
1486 record_insert (from + SCHARS (deletion), inschars);
1487 record_delete (from, deletion);
1490 GAP_SIZE -= outgoing_insbytes;
1491 GPT += inschars;
1492 ZV += inschars;
1493 Z += inschars;
1494 GPT_BYTE += outgoing_insbytes;
1495 ZV_BYTE += outgoing_insbytes;
1496 Z_BYTE += outgoing_insbytes;
1497 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1499 if (GPT_BYTE < GPT)
1500 abort ();
1502 /* Adjust the overlay center as needed. This must be done after
1503 adjusting the markers that bound the overlays. */
1504 adjust_overlays_for_delete (from, nchars_del);
1505 adjust_overlays_for_insert (from, inschars);
1507 /* Adjust markers for the deletion and the insertion. */
1508 if (markers)
1509 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1510 inschars, outgoing_insbytes);
1512 offset_intervals (current_buffer, from, inschars - nchars_del);
1514 /* Get the intervals for the part of the string we are inserting--
1515 not including the combined-before bytes. */
1516 intervals = STRING_INTERVALS (new);
1517 /* Insert those intervals. */
1518 graft_intervals_into_buffer (intervals, from, inschars,
1519 current_buffer, inherit);
1521 /* Relocate point as if it were a marker. */
1522 if (from < PT)
1523 adjust_point ((from + inschars - (PT < to ? PT : to)),
1524 (from_byte + outgoing_insbytes
1525 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
1527 if (outgoing_insbytes == 0)
1528 evaporate_overlays (from);
1530 CHECK_MARKERS ();
1532 MODIFF++;
1533 CHARS_MODIFF = MODIFF;
1534 UNGCPRO;
1536 signal_after_change (from, nchars_del, GPT - from);
1537 update_compositions (from, GPT, CHECK_BORDER);
1540 /* Replace the text from character positions FROM to TO with
1541 the text in INS of length INSCHARS.
1542 Keep the text properties that applied to the old characters
1543 (extending them to all the new chars if there are more new chars).
1545 Note that this does not yet handle markers quite right.
1547 If MARKERS is nonzero, relocate markers.
1549 Unlike most functions at this level, never call
1550 prepare_to_modify_buffer and never call signal_after_change. */
1552 void
1553 replace_range_2 (EMACS_INT from, EMACS_INT from_byte,
1554 EMACS_INT to, EMACS_INT to_byte,
1555 const char *ins, EMACS_INT inschars, EMACS_INT insbytes,
1556 int markers)
1558 EMACS_INT nbytes_del, nchars_del;
1559 Lisp_Object temp;
1561 CHECK_MARKERS ();
1563 nchars_del = to - from;
1564 nbytes_del = to_byte - from_byte;
1566 if (nbytes_del <= 0 && insbytes == 0)
1567 return;
1569 /* Make sure point-max won't overflow after this insertion. */
1570 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1571 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1572 error ("Maximum buffer size exceeded");
1574 /* Make sure the gap is somewhere in or next to what we are deleting. */
1575 if (from > GPT)
1576 gap_right (from, from_byte);
1577 if (to < GPT)
1578 gap_left (to, to_byte, 0);
1580 GAP_SIZE += nbytes_del;
1581 ZV -= nchars_del;
1582 Z -= nchars_del;
1583 ZV_BYTE -= nbytes_del;
1584 Z_BYTE -= nbytes_del;
1585 GPT = from;
1586 GPT_BYTE = from_byte;
1587 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1589 if (GPT_BYTE < GPT)
1590 abort ();
1592 if (GPT - BEG < BEG_UNCHANGED)
1593 BEG_UNCHANGED = GPT - BEG;
1594 if (Z - GPT < END_UNCHANGED)
1595 END_UNCHANGED = Z - GPT;
1597 if (GAP_SIZE < insbytes)
1598 make_gap (insbytes - GAP_SIZE);
1600 /* Copy the replacement text into the buffer. */
1601 memcpy (GPT_ADDR, ins, insbytes);
1603 #ifdef BYTE_COMBINING_DEBUG
1604 /* We have copied text into the gap, but we have not marked
1605 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1606 here, for both the previous text and the following text.
1607 Meanwhile, GPT_ADDR does point to
1608 the text that has been stored by copy_text. */
1609 if (count_combining_before (GPT_ADDR, insbytes, from, from_byte)
1610 || count_combining_after (GPT_ADDR, insbytes, from, from_byte))
1611 abort ();
1612 #endif
1614 GAP_SIZE -= insbytes;
1615 GPT += inschars;
1616 ZV += inschars;
1617 Z += inschars;
1618 GPT_BYTE += insbytes;
1619 ZV_BYTE += insbytes;
1620 Z_BYTE += insbytes;
1621 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1623 if (GPT_BYTE < GPT)
1624 abort ();
1626 /* Adjust the overlay center as needed. This must be done after
1627 adjusting the markers that bound the overlays. */
1628 if (nchars_del != inschars)
1630 adjust_overlays_for_insert (from, inschars);
1631 adjust_overlays_for_delete (from + inschars, nchars_del);
1634 /* Adjust markers for the deletion and the insertion. */
1635 if (markers
1636 && ! (nchars_del == 1 && inschars == 1 && nbytes_del == insbytes))
1637 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1638 inschars, insbytes);
1640 offset_intervals (current_buffer, from, inschars - nchars_del);
1642 /* Relocate point as if it were a marker. */
1643 if (from < PT && (nchars_del != inschars || nbytes_del != insbytes))
1645 if (PT < to)
1646 /* PT was within the deleted text. Move it to FROM. */
1647 adjust_point (from - PT, from_byte - PT_BYTE);
1648 else
1649 adjust_point (inschars - nchars_del, insbytes - nbytes_del);
1652 if (insbytes == 0)
1653 evaporate_overlays (from);
1655 CHECK_MARKERS ();
1657 MODIFF++;
1658 CHARS_MODIFF = MODIFF;
1661 /* Delete characters in current buffer
1662 from FROM up to (but not including) TO.
1663 If TO comes before FROM, we delete nothing. */
1665 void
1666 del_range (EMACS_INT from, EMACS_INT to)
1668 del_range_1 (from, to, 1, 0);
1671 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1672 RET_STRING says to return the deleted text. */
1674 Lisp_Object
1675 del_range_1 (EMACS_INT from, EMACS_INT to, int prepare, int ret_string)
1677 EMACS_INT from_byte, to_byte;
1678 Lisp_Object deletion;
1679 struct gcpro gcpro1;
1681 /* Make args be valid */
1682 if (from < BEGV)
1683 from = BEGV;
1684 if (to > ZV)
1685 to = ZV;
1687 if (to <= from)
1688 return Qnil;
1690 if (prepare)
1692 EMACS_INT range_length = to - from;
1693 prepare_to_modify_buffer (from, to, &from);
1694 to = min (ZV, from + range_length);
1697 from_byte = CHAR_TO_BYTE (from);
1698 to_byte = CHAR_TO_BYTE (to);
1700 deletion = del_range_2 (from, from_byte, to, to_byte, ret_string);
1701 GCPRO1(deletion);
1702 signal_after_change (from, to - from, 0);
1703 update_compositions (from, from, CHECK_HEAD);
1704 UNGCPRO;
1705 return deletion;
1708 /* Like del_range_1 but args are byte positions, not char positions. */
1710 void
1711 del_range_byte (EMACS_INT from_byte, EMACS_INT to_byte, int prepare)
1713 EMACS_INT from, to;
1715 /* Make args be valid */
1716 if (from_byte < BEGV_BYTE)
1717 from_byte = BEGV_BYTE;
1718 if (to_byte > ZV_BYTE)
1719 to_byte = ZV_BYTE;
1721 if (to_byte <= from_byte)
1722 return;
1724 from = BYTE_TO_CHAR (from_byte);
1725 to = BYTE_TO_CHAR (to_byte);
1727 if (prepare)
1729 EMACS_INT old_from = from, old_to = Z - to;
1730 EMACS_INT range_length = to - from;
1731 prepare_to_modify_buffer (from, to, &from);
1732 to = from + range_length;
1734 if (old_from != from)
1735 from_byte = CHAR_TO_BYTE (from);
1736 if (to > ZV)
1738 to = ZV;
1739 to_byte = ZV_BYTE;
1741 else if (old_to == Z - to)
1742 to_byte = CHAR_TO_BYTE (to);
1745 del_range_2 (from, from_byte, to, to_byte, 0);
1746 signal_after_change (from, to - from, 0);
1747 update_compositions (from, from, CHECK_HEAD);
1750 /* Like del_range_1, but positions are specified both as charpos
1751 and bytepos. */
1753 void
1754 del_range_both (EMACS_INT from, EMACS_INT from_byte,
1755 EMACS_INT to, EMACS_INT to_byte, int prepare)
1757 /* Make args be valid */
1758 if (from_byte < BEGV_BYTE)
1759 from_byte = BEGV_BYTE;
1760 if (to_byte > ZV_BYTE)
1761 to_byte = ZV_BYTE;
1763 if (to_byte <= from_byte)
1764 return;
1766 if (from < BEGV)
1767 from = BEGV;
1768 if (to > ZV)
1769 to = ZV;
1771 if (prepare)
1773 EMACS_INT old_from = from, old_to = Z - to;
1774 EMACS_INT range_length = to - from;
1775 prepare_to_modify_buffer (from, to, &from);
1776 to = from + range_length;
1778 if (old_from != from)
1779 from_byte = CHAR_TO_BYTE (from);
1780 if (to > ZV)
1782 to = ZV;
1783 to_byte = ZV_BYTE;
1785 else if (old_to == Z - to)
1786 to_byte = CHAR_TO_BYTE (to);
1789 del_range_2 (from, from_byte, to, to_byte, 0);
1790 signal_after_change (from, to - from, 0);
1791 update_compositions (from, from, CHECK_HEAD);
1794 /* Delete a range of text, specified both as character positions
1795 and byte positions. FROM and TO are character positions,
1796 while FROM_BYTE and TO_BYTE are byte positions.
1797 If RET_STRING is true, the deleted area is returned as a string. */
1799 Lisp_Object
1800 del_range_2 (EMACS_INT from, EMACS_INT from_byte,
1801 EMACS_INT to, EMACS_INT to_byte, int ret_string)
1803 register EMACS_INT nbytes_del, nchars_del;
1804 Lisp_Object deletion;
1806 CHECK_MARKERS ();
1808 nchars_del = to - from;
1809 nbytes_del = to_byte - from_byte;
1811 /* Make sure the gap is somewhere in or next to what we are deleting. */
1812 if (from > GPT)
1813 gap_right (from, from_byte);
1814 if (to < GPT)
1815 gap_left (to, to_byte, 0);
1817 #ifdef BYTE_COMBINING_DEBUG
1818 if (count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte),
1819 Z_BYTE - to_byte, from, from_byte))
1820 abort ();
1821 #endif
1823 if (ret_string || ! EQ (BVAR (current_buffer, undo_list), Qt))
1824 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1825 else
1826 deletion = Qnil;
1828 /* Relocate all markers pointing into the new, larger gap
1829 to point at the end of the text before the gap.
1830 Do this before recording the deletion,
1831 so that undo handles this after reinserting the text. */
1832 adjust_markers_for_delete (from, from_byte, to, to_byte);
1834 if (! EQ (BVAR (current_buffer, undo_list), Qt))
1835 record_delete (from, deletion);
1836 MODIFF++;
1837 CHARS_MODIFF = MODIFF;
1839 /* Relocate point as if it were a marker. */
1840 if (from < PT)
1841 adjust_point (from - (PT < to ? PT : to),
1842 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte));
1844 offset_intervals (current_buffer, from, - nchars_del);
1846 /* Adjust the overlay center as needed. This must be done after
1847 adjusting the markers that bound the overlays. */
1848 adjust_overlays_for_delete (from, nchars_del);
1850 GAP_SIZE += nbytes_del;
1851 ZV_BYTE -= nbytes_del;
1852 Z_BYTE -= nbytes_del;
1853 ZV -= nchars_del;
1854 Z -= nchars_del;
1855 GPT = from;
1856 GPT_BYTE = from_byte;
1857 if (GAP_SIZE > 0 && !current_buffer->text->inhibit_shrinking)
1858 /* Put an anchor, unless called from decode_coding_object which
1859 needs to access the previous gap contents. */
1860 *(GPT_ADDR) = 0;
1862 if (GPT_BYTE < GPT)
1863 abort ();
1865 if (GPT - BEG < BEG_UNCHANGED)
1866 BEG_UNCHANGED = GPT - BEG;
1867 if (Z - GPT < END_UNCHANGED)
1868 END_UNCHANGED = Z - GPT;
1870 CHECK_MARKERS ();
1872 evaporate_overlays (from);
1874 return deletion;
1877 /* Call this if you're about to change the region of BUFFER from
1878 character positions START to END. This checks the read-only
1879 properties of the region, calls the necessary modification hooks,
1880 and warns the next redisplay that it should pay attention to that
1881 area.
1883 If PRESERVE_CHARS_MODIFF is non-zero, do not update CHARS_MODIFF.
1884 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1886 void
1887 modify_region (struct buffer *buffer, EMACS_INT start, EMACS_INT end,
1888 int preserve_chars_modiff)
1890 struct buffer *old_buffer = current_buffer;
1892 if (buffer != old_buffer)
1893 set_buffer_internal (buffer);
1895 prepare_to_modify_buffer (start, end, NULL);
1897 BUF_COMPUTE_UNCHANGED (buffer, start - 1, end);
1899 if (MODIFF <= SAVE_MODIFF)
1900 record_first_change ();
1901 MODIFF++;
1902 if (! preserve_chars_modiff)
1903 CHARS_MODIFF = MODIFF;
1905 BVAR (buffer, point_before_scroll) = Qnil;
1907 if (buffer != old_buffer)
1908 set_buffer_internal (old_buffer);
1911 /* Check that it is okay to modify the buffer between START and END,
1912 which are char positions.
1914 Run the before-change-function, if any. If intervals are in use,
1915 verify that the text to be modified is not read-only, and call
1916 any modification properties the text may have.
1918 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
1919 by holding its value temporarily in a marker. */
1921 void
1922 prepare_to_modify_buffer (EMACS_INT start, EMACS_INT end,
1923 EMACS_INT *preserve_ptr)
1925 struct buffer *base_buffer;
1927 if (!NILP (BVAR (current_buffer, read_only)))
1928 Fbarf_if_buffer_read_only ();
1930 /* Let redisplay consider other windows than selected_window
1931 if modifying another buffer. */
1932 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
1933 ++windows_or_buffers_changed;
1935 if (BUF_INTERVALS (current_buffer) != 0)
1937 if (preserve_ptr)
1939 Lisp_Object preserve_marker;
1940 struct gcpro gcpro1;
1941 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
1942 GCPRO1 (preserve_marker);
1943 verify_interval_modification (current_buffer, start, end);
1944 *preserve_ptr = marker_position (preserve_marker);
1945 unchain_marker (XMARKER (preserve_marker));
1946 UNGCPRO;
1948 else
1949 verify_interval_modification (current_buffer, start, end);
1952 /* For indirect buffers, use the base buffer to check clashes. */
1953 if (current_buffer->base_buffer != 0)
1954 base_buffer = current_buffer->base_buffer;
1955 else
1956 base_buffer = current_buffer;
1958 #ifdef CLASH_DETECTION
1959 if (!NILP (BVAR (base_buffer, file_truename))
1960 /* Make binding buffer-file-name to nil effective. */
1961 && !NILP (BVAR (base_buffer, filename))
1962 && SAVE_MODIFF >= MODIFF)
1963 lock_file (BVAR (base_buffer, file_truename));
1964 #else
1965 /* At least warn if this file has changed on disk since it was visited. */
1966 if (!NILP (BVAR (base_buffer, filename))
1967 && SAVE_MODIFF >= MODIFF
1968 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
1969 && !NILP (Ffile_exists_p (BVAR (base_buffer, filename))))
1970 call1 (intern ("ask-user-about-supersession-threat"),
1971 BVAR (base_buffer,filename));
1972 #endif /* not CLASH_DETECTION */
1974 /* If `select-active-regions' is non-nil, save the region text. */
1975 if (!NILP (BVAR (current_buffer, mark_active))
1976 && !inhibit_modification_hooks
1977 && XMARKER (BVAR (current_buffer, mark))->buffer
1978 && NILP (Vsaved_region_selection)
1979 && (EQ (Vselect_active_regions, Qonly)
1980 ? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
1981 : (!NILP (Vselect_active_regions)
1982 && !NILP (Vtransient_mark_mode))))
1984 EMACS_INT b = XMARKER (BVAR (current_buffer, mark))->charpos;
1985 EMACS_INT e = PT;
1986 if (b < e)
1987 Vsaved_region_selection = make_buffer_string (b, e, 0);
1988 else if (b > e)
1989 Vsaved_region_selection = make_buffer_string (e, b, 0);
1992 signal_before_change (start, end, preserve_ptr);
1994 if (current_buffer->newline_cache)
1995 invalidate_region_cache (current_buffer,
1996 current_buffer->newline_cache,
1997 start - BEG, Z - end);
1998 if (current_buffer->width_run_cache)
1999 invalidate_region_cache (current_buffer,
2000 current_buffer->width_run_cache,
2001 start - BEG, Z - end);
2003 Vdeactivate_mark = Qt;
2006 /* These macros work with an argument named `preserve_ptr'
2007 and a local variable named `preserve_marker'. */
2009 #define PRESERVE_VALUE \
2010 if (preserve_ptr && NILP (preserve_marker)) \
2011 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2013 #define RESTORE_VALUE \
2014 if (! NILP (preserve_marker)) \
2016 *preserve_ptr = marker_position (preserve_marker); \
2017 unchain_marker (XMARKER (preserve_marker)); \
2020 #define PRESERVE_START_END \
2021 if (NILP (start_marker)) \
2022 start_marker = Fcopy_marker (start, Qnil); \
2023 if (NILP (end_marker)) \
2024 end_marker = Fcopy_marker (end, Qnil);
2026 #define FETCH_START \
2027 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2029 #define FETCH_END \
2030 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2032 /* Set a variable to nil if an error occurred.
2033 Don't change the variable if there was no error.
2034 VAL is a cons-cell (VARIABLE . NO-ERROR-FLAG).
2035 VARIABLE is the variable to maybe set to nil.
2036 NO-ERROR-FLAG is nil if there was an error,
2037 anything else meaning no error (so this function does nothing). */
2038 static Lisp_Object
2039 reset_var_on_error (Lisp_Object val)
2041 if (NILP (XCDR (val)))
2042 Fset (XCAR (val), Qnil);
2043 return Qnil;
2046 /* Signal a change to the buffer immediately before it happens.
2047 START_INT and END_INT are the bounds of the text to be changed.
2049 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2050 by holding its value temporarily in a marker. */
2052 void
2053 signal_before_change (EMACS_INT start_int, EMACS_INT end_int,
2054 EMACS_INT *preserve_ptr)
2056 Lisp_Object start, end;
2057 Lisp_Object start_marker, end_marker;
2058 Lisp_Object preserve_marker;
2059 struct gcpro gcpro1, gcpro2, gcpro3;
2060 int count = SPECPDL_INDEX ();
2062 if (inhibit_modification_hooks)
2063 return;
2065 start = make_number (start_int);
2066 end = make_number (end_int);
2067 preserve_marker = Qnil;
2068 start_marker = Qnil;
2069 end_marker = Qnil;
2070 GCPRO3 (preserve_marker, start_marker, end_marker);
2072 specbind (Qinhibit_modification_hooks, Qt);
2074 /* If buffer is unmodified, run a special hook for that case. The
2075 check for Vfirst_change_hook is just a minor optimization. */
2076 if (SAVE_MODIFF >= MODIFF
2077 && !NILP (Vfirst_change_hook))
2079 PRESERVE_VALUE;
2080 PRESERVE_START_END;
2081 Frun_hooks (1, &Qfirst_change_hook);
2084 /* Now run the before-change-functions if any. */
2085 if (!NILP (Vbefore_change_functions))
2087 Lisp_Object args[3];
2088 Lisp_Object rvoe_arg = Fcons (Qbefore_change_functions, Qnil);
2090 PRESERVE_VALUE;
2091 PRESERVE_START_END;
2093 /* Mark before-change-functions to be reset to nil in case of error. */
2094 record_unwind_protect (reset_var_on_error, rvoe_arg);
2096 /* Actually run the hook functions. */
2097 args[0] = Qbefore_change_functions;
2098 args[1] = FETCH_START;
2099 args[2] = FETCH_END;
2100 Frun_hook_with_args (3, args);
2102 /* There was no error: unarm the reset_on_error. */
2103 XSETCDR (rvoe_arg, Qt);
2106 if (current_buffer->overlays_before || current_buffer->overlays_after)
2108 PRESERVE_VALUE;
2109 report_overlay_modification (FETCH_START, FETCH_END, 0,
2110 FETCH_START, FETCH_END, Qnil);
2113 if (! NILP (start_marker))
2114 free_marker (start_marker);
2115 if (! NILP (end_marker))
2116 free_marker (end_marker);
2117 RESTORE_VALUE;
2118 UNGCPRO;
2120 unbind_to (count, Qnil);
2123 /* Signal a change immediately after it happens.
2124 CHARPOS is the character position of the start of the changed text.
2125 LENDEL is the number of characters of the text before the change.
2126 (Not the whole buffer; just the part that was changed.)
2127 LENINS is the number of characters in that part of the text
2128 after the change. */
2130 void
2131 signal_after_change (EMACS_INT charpos, EMACS_INT lendel, EMACS_INT lenins)
2133 int count = SPECPDL_INDEX ();
2134 if (inhibit_modification_hooks)
2135 return;
2137 /* If we are deferring calls to the after-change functions
2138 and there are no before-change functions,
2139 just record the args that we were going to use. */
2140 if (! NILP (Vcombine_after_change_calls)
2141 && NILP (Vbefore_change_functions)
2142 && !current_buffer->overlays_before
2143 && !current_buffer->overlays_after)
2145 Lisp_Object elt;
2147 if (!NILP (combine_after_change_list)
2148 && current_buffer != XBUFFER (combine_after_change_buffer))
2149 Fcombine_after_change_execute ();
2151 elt = Fcons (make_number (charpos - BEG),
2152 Fcons (make_number (Z - (charpos - lendel + lenins)),
2153 Fcons (make_number (lenins - lendel), Qnil)));
2154 combine_after_change_list
2155 = Fcons (elt, combine_after_change_list);
2156 combine_after_change_buffer = Fcurrent_buffer ();
2158 return;
2161 if (!NILP (combine_after_change_list))
2162 Fcombine_after_change_execute ();
2164 specbind (Qinhibit_modification_hooks, Qt);
2166 if (!NILP (Vafter_change_functions))
2168 Lisp_Object args[4];
2169 Lisp_Object rvoe_arg = Fcons (Qafter_change_functions, Qnil);
2171 /* Mark after-change-functions to be reset to nil in case of error. */
2172 record_unwind_protect (reset_var_on_error, rvoe_arg);
2174 /* Actually run the hook functions. */
2175 args[0] = Qafter_change_functions;
2176 XSETFASTINT (args[1], charpos);
2177 XSETFASTINT (args[2], charpos + lenins);
2178 XSETFASTINT (args[3], lendel);
2179 Frun_hook_with_args (4, args);
2181 /* There was no error: unarm the reset_on_error. */
2182 XSETCDR (rvoe_arg, Qt);
2185 if (current_buffer->overlays_before || current_buffer->overlays_after)
2186 report_overlay_modification (make_number (charpos),
2187 make_number (charpos + lenins),
2189 make_number (charpos),
2190 make_number (charpos + lenins),
2191 make_number (lendel));
2193 /* After an insertion, call the text properties
2194 insert-behind-hooks or insert-in-front-hooks. */
2195 if (lendel == 0)
2196 report_interval_modification (make_number (charpos),
2197 make_number (charpos + lenins));
2199 unbind_to (count, Qnil);
2202 static Lisp_Object
2203 Fcombine_after_change_execute_1 (Lisp_Object val)
2205 Vcombine_after_change_calls = val;
2206 return val;
2209 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
2210 Scombine_after_change_execute, 0, 0, 0,
2211 doc: /* This function is for use internally in `combine-after-change-calls'. */)
2212 (void)
2214 int count = SPECPDL_INDEX ();
2215 EMACS_INT beg, end, change;
2216 EMACS_INT begpos, endpos;
2217 Lisp_Object tail;
2219 if (NILP (combine_after_change_list))
2220 return Qnil;
2222 /* It is rare for combine_after_change_buffer to be invalid, but
2223 possible. It can happen when combine-after-change-calls is
2224 non-nil, and insertion calls a file handler (e.g. through
2225 lock_file) which scribbles into a temp file -- cyd */
2226 if (!BUFFERP (combine_after_change_buffer)
2227 || NILP (BVAR (XBUFFER (combine_after_change_buffer), name)))
2229 combine_after_change_list = Qnil;
2230 return Qnil;
2233 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
2235 Fset_buffer (combine_after_change_buffer);
2237 /* # chars unchanged at beginning of buffer. */
2238 beg = Z - BEG;
2239 /* # chars unchanged at end of buffer. */
2240 end = beg;
2241 /* Total amount of insertion (negative for deletion). */
2242 change = 0;
2244 /* Scan the various individual changes,
2245 accumulating the range info in BEG, END and CHANGE. */
2246 for (tail = combine_after_change_list; CONSP (tail);
2247 tail = XCDR (tail))
2249 Lisp_Object elt;
2250 EMACS_INT thisbeg, thisend, thischange;
2252 /* Extract the info from the next element. */
2253 elt = XCAR (tail);
2254 if (! CONSP (elt))
2255 continue;
2256 thisbeg = XINT (XCAR (elt));
2258 elt = XCDR (elt);
2259 if (! CONSP (elt))
2260 continue;
2261 thisend = XINT (XCAR (elt));
2263 elt = XCDR (elt);
2264 if (! CONSP (elt))
2265 continue;
2266 thischange = XINT (XCAR (elt));
2268 /* Merge this range into the accumulated range. */
2269 change += thischange;
2270 if (thisbeg < beg)
2271 beg = thisbeg;
2272 if (thisend < end)
2273 end = thisend;
2276 /* Get the current start and end positions of the range
2277 that was changed. */
2278 begpos = BEG + beg;
2279 endpos = Z - end;
2281 /* We are about to handle these, so discard them. */
2282 combine_after_change_list = Qnil;
2284 /* Now run the after-change functions for real.
2285 Turn off the flag that defers them. */
2286 record_unwind_protect (Fcombine_after_change_execute_1,
2287 Vcombine_after_change_calls);
2288 signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
2289 update_compositions (begpos, endpos, CHECK_ALL);
2291 return unbind_to (count, Qnil);
2294 void
2295 syms_of_insdel (void)
2297 staticpro (&combine_after_change_list);
2298 staticpro (&combine_after_change_buffer);
2299 combine_after_change_list = Qnil;
2300 combine_after_change_buffer = Qnil;
2302 DEFVAR_BOOL ("check-markers-debug-flag", check_markers_debug_flag,
2303 doc: /* Non-nil means enable debugging checks for invalid marker positions. */);
2304 check_markers_debug_flag = 0;
2305 DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls,
2306 doc: /* Used internally by the `combine-after-change-calls' macro. */);
2307 Vcombine_after_change_calls = Qnil;
2309 DEFVAR_BOOL ("inhibit-modification-hooks", inhibit_modification_hooks,
2310 doc: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2311 This affects `before-change-functions' and `after-change-functions',
2312 as well as hooks attached to text properties and overlays. */);
2313 inhibit_modification_hooks = 0;
2314 Qinhibit_modification_hooks = intern_c_string ("inhibit-modification-hooks");
2315 staticpro (&Qinhibit_modification_hooks);
2317 defsubr (&Scombine_after_change_execute);