(Ftry_completion, Fall_completions): Add a reference to
[emacs.git] / src / insdel.c
blob3cab83711baa007a0b3d32551b2f4fd8799bfbc3
1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 86,93,94,95,97,98, 1999 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
22 #include <config.h>
23 #include "lisp.h"
24 #include "intervals.h"
25 #include "buffer.h"
26 #include "charset.h"
27 #include "window.h"
28 #include "blockinput.h"
29 #include "region-cache.h"
31 #ifndef NULL
32 #define NULL 0
33 #endif
35 #define min(x, y) ((x) < (y) ? (x) : (y))
36 #define max(x, y) ((x) > (y) ? (x) : (y))
38 static void insert_from_string_1 P_ ((Lisp_Object, int, int, int, int, int, int));
39 static void insert_from_buffer_1 ();
40 static void gap_left P_ ((int, int, int));
41 static void gap_right P_ ((int, int));
42 static void adjust_markers_gap_motion P_ ((int, int, int));
43 static void adjust_markers_for_insert P_ ((int, int, int, int, int, int, int));
44 void adjust_markers_for_delete P_ ((int, int, int, int));
45 static void adjust_markers_for_record_delete P_ ((int, int, int, int));
46 static void adjust_point P_ ((int, int));
48 Lisp_Object Fcombine_after_change_execute ();
50 /* Non-nil means don't call the after-change-functions right away,
51 just record an element in Vcombine_after_change_calls_list. */
52 Lisp_Object Vcombine_after_change_calls;
54 /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
55 describing changes which happened while combine_after_change_calls
56 was nonzero. We use this to decide how to call them
57 once the deferral ends.
59 In each element.
60 BEG-UNCHANGED is the number of chars before the changed range.
61 END-UNCHANGED is the number of chars after the changed range,
62 and CHANGE-AMOUNT is the number of characters inserted by the change
63 (negative for a deletion). */
64 Lisp_Object combine_after_change_list;
66 /* Buffer which combine_after_change_list is about. */
67 Lisp_Object combine_after_change_buffer;
69 /* Check all markers in the current buffer, looking for something invalid. */
71 static int check_markers_debug_flag;
73 #define CHECK_MARKERS() \
74 if (check_markers_debug_flag) \
75 check_markers (); \
76 else
78 void
79 check_markers ()
81 register Lisp_Object tail;
82 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
84 tail = BUF_MARKERS (current_buffer);
86 while (XSYMBOL (tail) != XSYMBOL (Qnil))
88 if (XMARKER (tail)->buffer->text != current_buffer->text)
89 abort ();
90 if (XMARKER (tail)->charpos > Z)
91 abort ();
92 if (XMARKER (tail)->bytepos > Z_BYTE)
93 abort ();
94 if (multibyte && ! CHAR_HEAD_P (FETCH_BYTE (XMARKER (tail)->bytepos)))
95 abort ();
97 tail = XMARKER (tail)->chain;
101 /* Move gap to position CHARPOS.
102 Note that this can quit! */
104 void
105 move_gap (charpos)
106 int charpos;
108 move_gap_both (charpos, charpos_to_bytepos (charpos));
111 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
112 Note that this can quit! */
114 void
115 move_gap_both (charpos, bytepos)
116 int charpos, bytepos;
118 if (bytepos < GPT_BYTE)
119 gap_left (charpos, bytepos, 0);
120 else if (bytepos > GPT_BYTE)
121 gap_right (charpos, bytepos);
124 /* Move the gap to a position less than the current GPT.
125 BYTEPOS describes the new position as a byte position,
126 and CHARPOS is the corresponding char position.
127 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
129 static void
130 gap_left (charpos, bytepos, newgap)
131 register int charpos, bytepos;
132 int newgap;
134 register unsigned char *to, *from;
135 register int i;
136 int new_s1;
138 if (!newgap)
139 BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
141 i = GPT_BYTE;
142 to = GAP_END_ADDR;
143 from = GPT_ADDR;
144 new_s1 = GPT_BYTE;
146 /* Now copy the characters. To move the gap down,
147 copy characters up. */
149 while (1)
151 /* I gets number of characters left to copy. */
152 i = new_s1 - bytepos;
153 if (i == 0)
154 break;
155 /* If a quit is requested, stop copying now.
156 Change BYTEPOS to be where we have actually moved the gap to. */
157 if (QUITP)
159 bytepos = new_s1;
160 charpos = BYTE_TO_CHAR (bytepos);
161 break;
163 /* Move at most 32000 chars before checking again for a quit. */
164 if (i > 32000)
165 i = 32000;
166 #ifdef GAP_USE_BCOPY
167 if (i >= 128
168 /* bcopy is safe if the two areas of memory do not overlap
169 or on systems where bcopy is always safe for moving upward. */
170 && (BCOPY_UPWARD_SAFE
171 || to - from >= 128))
173 /* If overlap is not safe, avoid it by not moving too many
174 characters at once. */
175 if (!BCOPY_UPWARD_SAFE && i > to - from)
176 i = to - from;
177 new_s1 -= i;
178 from -= i, to -= i;
179 bcopy (from, to, i);
181 else
182 #endif
184 new_s1 -= i;
185 while (--i >= 0)
186 *--to = *--from;
190 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS.
191 BYTEPOS is where the loop above stopped, which may be what was specified
192 or may be where a quit was detected. */
193 adjust_markers_gap_motion (bytepos, GPT_BYTE, GAP_SIZE);
194 GPT_BYTE = bytepos;
195 GPT = charpos;
196 if (bytepos < charpos)
197 abort ();
198 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
199 QUIT;
202 /* Move the gap to a position greater than than the current GPT.
203 BYTEPOS describes the new position as a byte position,
204 and CHARPOS is the corresponding char position. */
206 static void
207 gap_right (charpos, bytepos)
208 register int charpos, bytepos;
210 register unsigned char *to, *from;
211 register int i;
212 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 (from, to, amount)
293 register int from, to, amount;
295 /* Now that a marker has a bytepos, not counting the gap,
296 nothing needs to be done here. */
297 #if 0
298 Lisp_Object marker;
299 register struct Lisp_Marker *m;
300 register int mpos;
302 marker = BUF_MARKERS (current_buffer);
304 while (!NILP (marker))
306 m = XMARKER (marker);
307 mpos = m->bytepos;
308 if (amount > 0)
310 if (mpos > to && mpos < to + amount)
312 if (adjust_markers_test)
313 abort ();
314 mpos = to + amount;
317 else
319 /* Here's the case where a marker is inside text being deleted.
320 AMOUNT can be negative for gap motion, too,
321 but then this range contains no markers. */
322 if (mpos > from + amount && mpos <= from)
324 if (adjust_markers_test)
325 abort ();
326 mpos = from + amount;
329 if (mpos > from && mpos <= to)
330 mpos += amount;
331 m->bufpos = mpos;
332 marker = m->chain;
334 #endif
337 /* Adjust all markers for a deletion
338 whose range in bytes is FROM_BYTE to TO_BYTE.
339 The range in charpos is FROM to TO.
341 This function assumes that the gap is adjacent to
342 or inside of the range being deleted. */
344 void
345 adjust_markers_for_delete (from, from_byte, to, to_byte)
346 register int from, from_byte, to, to_byte;
348 Lisp_Object marker;
349 register struct Lisp_Marker *m;
350 register int charpos;
352 marker = BUF_MARKERS (current_buffer);
354 while (!NILP (marker))
356 m = XMARKER (marker);
357 charpos = m->charpos;
359 if (charpos > Z)
360 abort ();
362 /* If the marker is after the deletion,
363 relocate by number of chars / bytes deleted. */
364 if (charpos > to)
366 m->charpos -= to - from;
367 m->bytepos -= to_byte - from_byte;
370 /* Here's the case where a marker is inside text being deleted. */
371 else if (charpos > from)
373 record_marker_adjustment (marker, from - charpos);
374 m->charpos = from;
375 m->bytepos = from_byte;
378 marker = m->chain;
383 /* Adjust all markers for calling record_delete for combining bytes.
384 whose range in bytes is FROM_BYTE to TO_BYTE.
385 The range in charpos is FROM to TO. */
387 static void
388 adjust_markers_for_record_delete (from, from_byte, to, to_byte)
389 register int from, from_byte, to, to_byte;
391 Lisp_Object marker;
392 register struct Lisp_Marker *m;
393 register int charpos;
395 marker = BUF_MARKERS (current_buffer);
397 while (!NILP (marker))
399 m = XMARKER (marker);
400 charpos = m->charpos;
402 /* If the marker is after the deletion,
403 relocate by number of chars / bytes deleted. */
404 if (charpos > to)
406 /* Here's the case where a marker is inside text being deleted. */
407 else if (charpos > from)
408 record_marker_adjustment (marker, from - charpos);
410 marker = m->chain;
414 /* Adjust markers for an insertion that stretches from FROM / FROM_BYTE
415 to TO / TO_BYTE. We have to relocate the charpos of every marker
416 that points after the insertion (but not their bytepos).
418 COMBINED_BEFORE_BYTES is the number of bytes at the start of the insertion
419 that combine into one character with the text before the insertion.
420 COMBINED_AFTER_BYTES is the number of bytes after the insertion
421 that combine into one character with the last inserted bytes.
423 When a marker points at the insertion point,
424 we advance it if either its insertion-type is t
425 or BEFORE_MARKERS is true. */
427 static void
428 adjust_markers_for_insert (from, from_byte, to, to_byte,
429 combined_before_bytes, combined_after_bytes,
430 before_markers)
431 register int from, from_byte, to, to_byte;
432 int combined_before_bytes, combined_after_bytes, before_markers;
434 Lisp_Object marker;
435 int adjusted = 0;
436 int nchars = to - from;
437 int nbytes = to_byte - from_byte;
439 marker = BUF_MARKERS (current_buffer);
441 while (!NILP (marker))
443 register struct Lisp_Marker *m = XMARKER (marker);
445 /* In a single-byte buffer, a marker's two positions must be equal.
446 (If this insertion is going to combine characters, Z will
447 become different from Z_BYTE, but they might be the same now.
448 If so, the two OLD positions of the marker should be equal.) */
449 if (Z == Z_BYTE)
451 if (m->charpos != m->bytepos)
452 abort ();
455 if (m->bytepos == from_byte)
457 if (m->insertion_type || before_markers)
459 m->bytepos = to_byte + combined_after_bytes;
460 m->charpos = to - combined_before_bytes;
461 /* Point the marker before the combined character,
462 so that undoing the insertion puts it back where it was. */
463 if (combined_after_bytes)
464 DEC_BOTH (m->charpos, m->bytepos);
465 if (m->insertion_type)
466 adjusted = 1;
468 else if (combined_before_bytes)
470 /* This marker doesn't "need relocation",
471 but don't leave it pointing in the middle of a character.
472 Point the marker after the combined character,
473 so that undoing the insertion puts it back where it was. */
474 m->bytepos += combined_before_bytes;
475 if (combined_before_bytes == nbytes)
476 /* All new bytes plus combined_after_bytes (if any)
477 are combined. */
478 m->bytepos += combined_after_bytes;
481 /* If a marker was pointing into the combining bytes
482 after the insertion, don't leave it there
483 in the middle of a character. */
484 else if (combined_after_bytes && m->bytepos >= from_byte
485 && m->bytepos < from_byte + combined_after_bytes)
487 /* Put it after the combining bytes. */
488 m->bytepos = to_byte + combined_after_bytes;
489 m->charpos = to - combined_before_bytes;
490 /* Now move it back before the combined character,
491 so that undoing the insertion will put it where it was. */
492 DEC_BOTH (m->charpos, m->bytepos);
494 else if (m->bytepos > from_byte)
496 m->bytepos += nbytes;
497 m->charpos += nchars - combined_after_bytes - combined_before_bytes;
500 marker = m->chain;
503 /* Adjusting only markers whose insertion-type is t may result in
504 disordered overlays in the slot `overlays_before'. */
505 if (adjusted)
506 fix_overlays_before (current_buffer, from, to);
509 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters.
511 This is used only when the value of point changes due to an insert
512 or delete; it does not represent a conceptual change in point as a
513 marker. In particular, point is not crossing any interval
514 boundaries, so there's no need to use the usual SET_PT macro. In
515 fact it would be incorrect to do so, because either the old or the
516 new value of point is out of sync with the current set of
517 intervals. */
519 static void
520 adjust_point (nchars, nbytes)
521 int nchars, nbytes;
523 BUF_PT (current_buffer) += nchars;
524 BUF_PT_BYTE (current_buffer) += nbytes;
526 /* In a single-byte buffer, the two positions must be equal. */
527 if (ZV == ZV_BYTE
528 && PT != PT_BYTE)
529 abort ();
532 /* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
533 length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
534 (NEW_BYTES).
536 See the comment of adjust_markers_for_insert for the args
537 COMBINED_BEFORE_BYTES and COMBINED_AFTER_BYTES. */
539 static void
540 adjust_markers_for_replace (from, from_byte, old_chars, old_bytes,
541 new_chars, new_bytes,
542 combined_before_bytes, combined_after_bytes)
543 int from, from_byte, old_chars, old_bytes, new_chars, new_bytes;
544 int combined_before_bytes, combined_after_bytes;
546 Lisp_Object marker = BUF_MARKERS (current_buffer);
547 int prev_to_byte = from_byte + old_bytes;
548 int diff_chars
549 = (new_chars - combined_before_bytes) - (old_chars + combined_after_bytes);
550 int diff_bytes = new_bytes - old_bytes;
552 while (!NILP (marker))
554 register struct Lisp_Marker *m = XMARKER (marker);
556 if (m->bytepos >= prev_to_byte
557 && (old_bytes != 0
558 /* If this is an insertion (replacing 0 chars),
559 reject the case of a marker that is at the
560 insertion point and should stay before the insertion. */
561 || m->bytepos > from_byte || m->insertion_type))
563 if (m->bytepos < prev_to_byte + combined_after_bytes)
565 /* Put it after the combining bytes. */
566 m->bytepos = from_byte + new_bytes + combined_after_bytes;
567 m->charpos = from + new_chars - combined_before_bytes;
569 else
571 m->charpos = min (from + new_chars, m->charpos + diff_chars);
572 m->bytepos = min (from_byte + new_bytes,
573 m->bytepos + diff_bytes);
576 else if (m->bytepos >= from_byte)
578 m->charpos = from;
579 m->bytepos = from_byte + combined_before_bytes;
580 /* If all new bytes are combined in addition to that there
581 are after combining bytes, we must set byte position of
582 the marker after the after combining bytes. */
583 if (combined_before_bytes == new_bytes)
584 m->bytepos += combined_after_bytes;
587 marker = m->chain;
590 CHECK_MARKERS ();
594 /* Make the gap NBYTES_ADDED bytes longer. */
596 void
597 make_gap (nbytes_added)
598 int nbytes_added;
600 unsigned char *result;
601 Lisp_Object tem;
602 int real_gap_loc;
603 int real_gap_loc_byte;
604 int old_gap_size;
606 /* If we have to get more space, get enough to last a while. */
607 nbytes_added += 2000;
609 /* Don't allow a buffer size that won't fit in an int
610 even if it will fit in a Lisp integer.
611 That won't work because so many places use `int'. */
613 if (Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added
614 >= ((unsigned) 1 << (min (BITS_PER_INT, VALBITS) - 1)))
615 error ("Buffer exceeds maximum size");
617 BLOCK_INPUT;
618 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */
619 result = BUFFER_REALLOC (BEG_ADDR, (Z_BYTE - BEG_BYTE
620 + GAP_SIZE + nbytes_added + 1));
622 if (result == 0)
624 UNBLOCK_INPUT;
625 memory_full ();
628 /* We can't unblock until the new address is properly stored. */
629 BEG_ADDR = result;
630 UNBLOCK_INPUT;
632 /* Prevent quitting in move_gap. */
633 tem = Vinhibit_quit;
634 Vinhibit_quit = Qt;
636 real_gap_loc = GPT;
637 real_gap_loc_byte = GPT_BYTE;
638 old_gap_size = GAP_SIZE;
640 /* Call the newly allocated space a gap at the end of the whole space. */
641 GPT = Z + GAP_SIZE;
642 GPT_BYTE = Z_BYTE + GAP_SIZE;
643 GAP_SIZE = nbytes_added;
645 /* Move the new gap down to be consecutive with the end of the old one.
646 This adjusts the markers properly too. */
647 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
649 /* Now combine the two into one large gap. */
650 GAP_SIZE += old_gap_size;
651 GPT = real_gap_loc;
652 GPT_BYTE = real_gap_loc_byte;
654 /* Put an anchor. */
655 *(Z_ADDR) = 0;
657 Vinhibit_quit = tem;
660 /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR.
661 FROM_MULTIBYTE says whether the incoming text is multibyte.
662 TO_MULTIBYTE says whether to store the text as multibyte.
663 If FROM_MULTIBYTE != TO_MULTIBYTE, we convert.
665 Return the number of bytes stored at TO_ADDR. */
668 copy_text (from_addr, to_addr, nbytes,
669 from_multibyte, to_multibyte)
670 unsigned char *from_addr;
671 unsigned char *to_addr;
672 int nbytes;
673 int from_multibyte, to_multibyte;
675 if (from_multibyte == to_multibyte)
677 bcopy (from_addr, to_addr, nbytes);
678 return nbytes;
680 else if (from_multibyte)
682 int nchars = 0;
683 int bytes_left = nbytes;
684 Lisp_Object tbl = Qnil;
686 /* We set the variable tbl to the reverse table of
687 Vnonascii_translation_table in advance. */
688 if (CHAR_TABLE_P (Vnonascii_translation_table))
690 tbl = Fchar_table_extra_slot (Vnonascii_translation_table,
691 make_number (0));
692 if (!CHAR_TABLE_P (tbl))
693 tbl = Qnil;
696 /* Convert multibyte to single byte. */
697 while (bytes_left > 0)
699 int thislen, c, c_save;
700 c = c_save = STRING_CHAR_AND_LENGTH (from_addr, bytes_left, thislen);
701 if (!SINGLE_BYTE_CHAR_P (c))
702 c = multibyte_char_to_unibyte (c, tbl);
703 *to_addr++ = c;
704 from_addr += thislen;
705 bytes_left -= thislen;
706 nchars++;
708 return nchars;
710 else
712 unsigned char *initial_to_addr = to_addr;
714 /* Convert single-byte to multibyte. */
715 while (nbytes > 0)
717 int c = *from_addr++;
719 if (c < 0400
720 && (c >= 0240
721 || (c >= 0200 && !NILP (Vnonascii_translation_table))))
723 c = unibyte_char_to_multibyte (c);
724 to_addr += CHAR_STRING (c, to_addr);
725 nbytes--;
727 else
728 /* Special case for speed. */
729 *to_addr++ = c, nbytes--;
731 return to_addr - initial_to_addr;
735 /* Return the number of bytes it would take
736 to convert some single-byte text to multibyte.
737 The single-byte text consists of NBYTES bytes at PTR. */
740 count_size_as_multibyte (ptr, nbytes)
741 unsigned char *ptr;
742 int nbytes;
744 int i;
745 int outgoing_nbytes = 0;
747 for (i = 0; i < nbytes; i++)
749 unsigned int c = *ptr++;
751 if (c < 0200 || (c < 0240 && NILP (Vnonascii_translation_table)))
752 outgoing_nbytes++;
753 else
755 c = unibyte_char_to_multibyte (c);
756 outgoing_nbytes += CHAR_BYTES (c);
760 return outgoing_nbytes;
763 /* Insert a string of specified length before point.
764 This function judges multibyteness based on
765 enable_multibyte_characters in the current buffer;
766 it never converts between single-byte and multibyte.
768 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
769 prepare_to_modify_buffer could relocate the text. */
771 void
772 insert (string, nbytes)
773 register unsigned char *string;
774 register int nbytes;
776 if (nbytes > 0)
778 int opoint = PT;
779 insert_1 (string, nbytes, 0, 1, 0);
780 signal_after_change (opoint, 0, PT - opoint);
781 update_compositions (opoint, PT, CHECK_BORDER);
785 /* Likewise, but inherit text properties from neighboring characters. */
787 void
788 insert_and_inherit (string, nbytes)
789 register unsigned char *string;
790 register int nbytes;
792 if (nbytes > 0)
794 int opoint = PT;
795 insert_1 (string, nbytes, 1, 1, 0);
796 signal_after_change (opoint, 0, PT - opoint);
797 update_compositions (opoint, PT, CHECK_BORDER);
801 /* Insert the character C before point. Do not inherit text properties. */
803 void
804 insert_char (c)
805 int c;
807 unsigned char str[MAX_MULTIBYTE_LENGTH];
808 int len;
810 if (! NILP (current_buffer->enable_multibyte_characters))
811 len = CHAR_STRING (c, str);
812 else
814 len = 1;
815 str[0] = c;
818 insert (str, len);
821 /* Insert the null-terminated string S before point. */
823 void
824 insert_string (s)
825 char *s;
827 insert (s, strlen (s));
830 /* Like `insert' except that all markers pointing at the place where
831 the insertion happens are adjusted to point after it.
832 Don't use this function to insert part of a Lisp string,
833 since gc could happen and relocate it. */
835 void
836 insert_before_markers (string, nbytes)
837 unsigned char *string;
838 register int nbytes;
840 if (nbytes > 0)
842 int opoint = PT;
844 insert_1 (string, nbytes, 0, 1, 1);
845 signal_after_change (opoint, 0, PT - opoint);
846 update_compositions (opoint, PT, CHECK_BORDER);
850 /* Likewise, but inherit text properties from neighboring characters. */
852 void
853 insert_before_markers_and_inherit (string, nbytes)
854 unsigned char *string;
855 register int nbytes;
857 if (nbytes > 0)
859 int opoint = PT;
861 insert_1 (string, nbytes, 1, 1, 1);
862 signal_after_change (opoint, 0, PT - opoint);
863 update_compositions (opoint, PT, CHECK_BORDER);
867 /* Subroutine used by the insert functions above. */
869 void
870 insert_1 (string, nbytes, inherit, prepare, before_markers)
871 register unsigned char *string;
872 register int nbytes;
873 int inherit, prepare, before_markers;
875 insert_1_both (string, chars_in_text (string, nbytes), nbytes,
876 inherit, prepare, before_markers);
879 /* See if the bytes before POS/POS_BYTE combine with bytes
880 at the start of STRING to form a single character.
881 If so, return the number of bytes at the start of STRING
882 which combine in this way. Otherwise, return 0. */
885 count_combining_before (string, length, pos, pos_byte)
886 unsigned char *string;
887 int length;
888 int pos, pos_byte;
890 int len, combining_bytes;
891 unsigned char *p;
893 if (NILP (current_buffer->enable_multibyte_characters))
894 return 0;
896 /* At first, we can exclude the following cases:
897 (1) STRING[0] can't be a following byte of multibyte sequence.
898 (2) POS is the start of the current buffer.
899 (3) A character before POS is not a multibyte character. */
900 if (length == 0 || CHAR_HEAD_P (*string)) /* case (1) */
901 return 0;
902 if (pos_byte == BEG_BYTE) /* case (2) */
903 return 0;
904 len = 1;
905 p = BYTE_POS_ADDR (pos_byte - 1);
906 while (! CHAR_HEAD_P (*p)) p--, len++;
907 if (! BASE_LEADING_CODE_P (*p)) /* case (3) */
908 return 0;
910 combining_bytes = BYTES_BY_CHAR_HEAD (*p) - len;
911 if (combining_bytes <= 0)
912 /* The character preceding POS is, complete and no room for
913 combining bytes (combining_bytes == 0), or an independent 8-bit
914 character (combining_bytes < 0). */
915 return 0;
917 /* We have a combination situation. Count the bytes at STRING that
918 may combine. */
919 p = string + 1;
920 while (!CHAR_HEAD_P (*p) && p < string + length)
921 p++;
923 return (combining_bytes < p - string ? combining_bytes : p - string);
926 /* See if the bytes after POS/POS_BYTE combine with bytes
927 at the end of STRING to form a single character.
928 If so, return the number of bytes after POS/POS_BYTE
929 which combine in this way. Otherwise, return 0. */
932 count_combining_after (string, length, pos, pos_byte)
933 unsigned char *string;
934 int length;
935 int pos, pos_byte;
937 int opos_byte = pos_byte;
938 int i;
939 int bytes;
940 unsigned char *bufp;
942 if (NILP (current_buffer->enable_multibyte_characters))
943 return 0;
945 /* At first, we can exclude the following cases:
946 (1) The last byte of STRING is an ASCII.
947 (2) POS is the last of the current buffer.
948 (3) A character at POS can't be a following byte of multibyte
949 character. */
950 if (length > 0 && ASCII_BYTE_P (string[length - 1])) /* case (1) */
951 return 0;
952 if (pos_byte == Z_BYTE) /* case (2) */
953 return 0;
954 bufp = BYTE_POS_ADDR (pos_byte);
955 if (CHAR_HEAD_P (*bufp)) /* case (3) */
956 return 0;
958 i = length - 1;
959 while (i >= 0 && ! CHAR_HEAD_P (string[i]))
961 i--;
963 if (i < 0)
965 /* All characters in STRING are not character head. We must
966 check also preceding bytes at POS. We are sure that the gap
967 is at POS. */
968 unsigned char *p = BEG_ADDR;
969 i = pos_byte - 2;
970 while (i >= 0 && ! CHAR_HEAD_P (p[i]))
971 i--;
972 if (i < 0 || !BASE_LEADING_CODE_P (p[i]))
973 return 0;
975 bytes = BYTES_BY_CHAR_HEAD (p[i]);
976 return (bytes <= pos_byte - 1 - i + length
978 : bytes - (pos_byte - 1 - i + length));
980 if (!BASE_LEADING_CODE_P (string[i]))
981 return 0;
983 bytes = BYTES_BY_CHAR_HEAD (string[i]) - (length - i);
984 bufp++, pos_byte++;
985 while (!CHAR_HEAD_P (*bufp)) bufp++, pos_byte++;
987 return (bytes <= pos_byte - opos_byte ? bytes : pos_byte - opos_byte);
990 /* Adjust the position TARGET/TARGET_BYTE for the combining of NBYTES
991 following the position POS/POS_BYTE to the character preceding POS.
992 If TARGET is after POS+NBYTES, we only have to adjust the character
993 position TARGET, else, if TARGET is after POS, we have to adjust
994 both the character position TARGET and the byte position
995 TARGET_BYTE, else we don't have to do any adjustment. */
997 #define ADJUST_CHAR_POS(target, target_byte) \
998 do { \
999 if (target > pos + nbytes) \
1000 target -= nbytes; \
1001 else if (target >= pos) \
1003 target = pos; \
1004 target_byte = pos_byte + nbytes; \
1006 } while (0)
1008 /* Combine NBYTES stray trailing-codes, which were formerly separate
1009 characters, with the preceding character. These bytes
1010 are located after position POS / POS_BYTE, and the preceding character
1011 is located just before that position.
1013 This function does not adjust markers for byte combining. That
1014 should be done in advance by the functions
1015 adjust_markers_for_insert or adjust_markers_for_replace. */
1017 static void
1018 combine_bytes (pos, pos_byte, nbytes)
1019 int pos, pos_byte, nbytes;
1021 adjust_overlays_for_delete (pos, nbytes);
1023 ADJUST_CHAR_POS (BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer));
1024 ADJUST_CHAR_POS (GPT, GPT_BYTE);
1025 ADJUST_CHAR_POS (Z, Z_BYTE);
1026 ADJUST_CHAR_POS (ZV, ZV_BYTE);
1028 if (BUF_INTERVALS (current_buffer) != 0)
1029 offset_intervals (current_buffer, pos, - nbytes);
1032 void
1033 byte_combining_error ()
1035 error ("Byte combining across boundary of accessible buffer text inhibitted");
1038 /* If we are going to combine bytes at POS which is at a narrowed
1039 region boundary, signal an error. */
1040 #define CHECK_BYTE_COMBINING_FOR_INSERT(pos) \
1041 do { \
1042 if ((combined_before_bytes && pos == BEGV) \
1043 || (combined_after_bytes && pos == ZV)) \
1044 byte_combining_error (); \
1045 } while (0)
1048 /* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1049 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
1050 are the same as in insert_1. */
1052 void
1053 insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers)
1054 register unsigned char *string;
1055 register int nchars, nbytes;
1056 int inherit, prepare, before_markers;
1058 int combined_before_bytes, combined_after_bytes;
1060 if (NILP (current_buffer->enable_multibyte_characters))
1061 nchars = nbytes;
1063 if (prepare)
1064 /* Do this before moving and increasing the gap,
1065 because the before-change hooks might move the gap
1066 or make it smaller. */
1067 prepare_to_modify_buffer (PT, PT, NULL);
1069 if (PT != GPT)
1070 move_gap_both (PT, PT_BYTE);
1071 if (GAP_SIZE < nbytes)
1072 make_gap (nbytes - GAP_SIZE);
1074 combined_before_bytes
1075 = count_combining_before (string, nbytes, PT, PT_BYTE);
1076 combined_after_bytes
1077 = count_combining_after (string, nbytes, PT, PT_BYTE);
1078 CHECK_BYTE_COMBINING_FOR_INSERT (PT);
1080 /* Record deletion of the surrounding text that combines with
1081 the insertion. This, together with recording the insertion,
1082 will add up to the right stuff in the undo list.
1084 But there is no need to actually delete the combining bytes
1085 from the buffer and reinsert them. */
1087 if (combined_after_bytes)
1089 Lisp_Object deletion;
1090 deletion = Qnil;
1092 if (! EQ (current_buffer->undo_list, Qt))
1093 deletion = make_buffer_string_both (PT, PT_BYTE,
1094 PT + combined_after_bytes,
1095 PT_BYTE + combined_after_bytes, 1);
1097 adjust_markers_for_record_delete (PT, PT_BYTE,
1098 PT + combined_after_bytes,
1099 PT_BYTE + combined_after_bytes);
1100 if (! EQ (current_buffer->undo_list, Qt))
1101 record_delete (PT, deletion);
1104 if (combined_before_bytes)
1106 Lisp_Object deletion;
1107 deletion = Qnil;
1109 if (! EQ (current_buffer->undo_list, Qt))
1110 deletion = make_buffer_string_both (PT - 1, CHAR_TO_BYTE (PT - 1),
1111 PT, PT_BYTE, 1);
1112 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
1113 PT, PT_BYTE);
1114 if (! EQ (current_buffer->undo_list, Qt))
1115 record_delete (PT - 1, deletion);
1118 record_insert (PT - !!combined_before_bytes,
1119 nchars - combined_before_bytes + !!combined_before_bytes);
1120 MODIFF++;
1122 bcopy (string, GPT_ADDR, nbytes);
1124 GAP_SIZE -= nbytes;
1125 /* When we have combining at the end of the insertion,
1126 this is the character position before the combined character. */
1127 GPT += nchars;
1128 ZV += nchars;
1129 Z += nchars;
1130 GPT_BYTE += nbytes;
1131 ZV_BYTE += nbytes;
1132 Z_BYTE += nbytes;
1133 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1135 if (combined_after_bytes)
1136 move_gap_both (GPT + combined_after_bytes,
1137 GPT_BYTE + combined_after_bytes);
1139 if (GPT_BYTE < GPT)
1140 abort ();
1142 adjust_overlays_for_insert (PT, nchars);
1143 adjust_markers_for_insert (PT, PT_BYTE,
1144 PT + nchars, PT_BYTE + nbytes,
1145 combined_before_bytes, combined_after_bytes,
1146 before_markers);
1148 if (BUF_INTERVALS (current_buffer) != 0)
1149 offset_intervals (current_buffer, PT, nchars);
1151 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
1152 set_text_properties (make_number (PT), make_number (PT + nchars),
1153 Qnil, Qnil, Qnil);
1156 int pos = PT, pos_byte = PT_BYTE;
1158 adjust_point (nchars + combined_after_bytes,
1159 nbytes + combined_after_bytes);
1161 if (combined_after_bytes)
1162 combine_bytes (pos + nchars, pos_byte + nbytes, combined_after_bytes);
1164 if (combined_before_bytes)
1165 combine_bytes (pos, pos_byte, combined_before_bytes);
1168 CHECK_MARKERS ();
1171 /* Insert the part of the text of STRING, a Lisp object assumed to be
1172 of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes)
1173 starting at position POS / POS_BYTE. If the text of STRING has properties,
1174 copy them into the buffer.
1176 It does not work to use `insert' for this, because a GC could happen
1177 before we bcopy the stuff into the buffer, and relocate the string
1178 without insert noticing. */
1180 void
1181 insert_from_string (string, pos, pos_byte, length, length_byte, inherit)
1182 Lisp_Object string;
1183 register int pos, pos_byte, length, length_byte;
1184 int inherit;
1186 int opoint = PT;
1187 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1188 inherit, 0);
1189 signal_after_change (opoint, 0, PT - opoint);
1190 update_compositions (opoint, PT, CHECK_BORDER);
1193 /* Like `insert_from_string' except that all markers pointing
1194 at the place where the insertion happens are adjusted to point after it. */
1196 void
1197 insert_from_string_before_markers (string, pos, pos_byte,
1198 length, length_byte, inherit)
1199 Lisp_Object string;
1200 register int pos, pos_byte, length, length_byte;
1201 int inherit;
1203 int opoint = PT;
1204 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1205 inherit, 1);
1206 signal_after_change (opoint, 0, PT - opoint);
1207 update_compositions (opoint, PT, CHECK_BORDER);
1210 /* Subroutine of the insertion functions above. */
1212 static void
1213 insert_from_string_1 (string, pos, pos_byte, nchars, nbytes,
1214 inherit, before_markers)
1215 Lisp_Object string;
1216 register int pos, pos_byte, nchars, nbytes;
1217 int inherit, before_markers;
1219 struct gcpro gcpro1;
1220 int outgoing_nbytes = nbytes;
1221 int combined_before_bytes, combined_after_bytes;
1222 INTERVAL intervals;
1224 /* Make OUTGOING_NBYTES describe the text
1225 as it will be inserted in this buffer. */
1227 if (NILP (current_buffer->enable_multibyte_characters))
1228 outgoing_nbytes = nchars;
1229 else if (! STRING_MULTIBYTE (string))
1230 outgoing_nbytes
1231 = count_size_as_multibyte (&XSTRING (string)->data[pos_byte],
1232 nbytes);
1234 GCPRO1 (string);
1235 /* Do this before moving and increasing the gap,
1236 because the before-change hooks might move the gap
1237 or make it smaller. */
1238 prepare_to_modify_buffer (PT, PT, NULL);
1240 if (PT != GPT)
1241 move_gap_both (PT, PT_BYTE);
1242 if (GAP_SIZE < outgoing_nbytes)
1243 make_gap (outgoing_nbytes - GAP_SIZE);
1244 UNGCPRO;
1246 /* Copy the string text into the buffer, perhaps converting
1247 between single-byte and multibyte. */
1248 copy_text (XSTRING (string)->data + pos_byte, GPT_ADDR, nbytes,
1249 STRING_MULTIBYTE (string),
1250 ! NILP (current_buffer->enable_multibyte_characters));
1252 /* We have copied text into the gap, but we have not altered
1253 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1254 to these functions and get the same results as we would
1255 have got earlier on. Meanwhile, PT_ADDR does point to
1256 the text that has been stored by copy_text. */
1258 combined_before_bytes
1259 = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1260 combined_after_bytes
1261 = count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1263 unsigned char save = *(GPT_ADDR);
1264 *(GPT_ADDR) = 0;
1265 CHECK_BYTE_COMBINING_FOR_INSERT (PT);
1266 *(GPT_ADDR) = save;
1269 /* Record deletion of the surrounding text that combines with
1270 the insertion. This, together with recording the insertion,
1271 will add up to the right stuff in the undo list.
1273 But there is no need to actually delete the combining bytes
1274 from the buffer and reinsert them. */
1276 if (combined_after_bytes)
1278 Lisp_Object deletion;
1279 deletion = Qnil;
1281 if (! EQ (current_buffer->undo_list, Qt))
1282 deletion = make_buffer_string_both (PT, PT_BYTE,
1283 PT + combined_after_bytes,
1284 PT_BYTE + combined_after_bytes, 1);
1286 adjust_markers_for_record_delete (PT, PT_BYTE,
1287 PT + combined_after_bytes,
1288 PT_BYTE + combined_after_bytes);
1289 if (! EQ (current_buffer->undo_list, Qt))
1290 record_delete (PT, deletion);
1293 if (combined_before_bytes)
1295 Lisp_Object deletion;
1296 deletion = Qnil;
1298 if (! EQ (current_buffer->undo_list, Qt))
1299 deletion = make_buffer_string_both (PT - 1, CHAR_TO_BYTE (PT - 1),
1300 PT, PT_BYTE, 1);
1301 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
1302 PT, PT_BYTE);
1303 if (! EQ (current_buffer->undo_list, Qt))
1304 record_delete (PT - 1, deletion);
1307 record_insert (PT - !!combined_before_bytes,
1308 nchars - combined_before_bytes + !!combined_before_bytes);
1309 MODIFF++;
1311 GAP_SIZE -= outgoing_nbytes;
1312 GPT += nchars;
1313 ZV += nchars;
1314 Z += nchars;
1315 GPT_BYTE += outgoing_nbytes;
1316 ZV_BYTE += outgoing_nbytes;
1317 Z_BYTE += outgoing_nbytes;
1318 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1320 if (combined_after_bytes)
1321 move_gap_both (GPT + combined_after_bytes,
1322 GPT_BYTE + combined_after_bytes);
1324 if (GPT_BYTE < GPT)
1325 abort ();
1327 adjust_overlays_for_insert (PT, nchars);
1328 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1329 PT_BYTE + outgoing_nbytes,
1330 combined_before_bytes, combined_after_bytes,
1331 before_markers);
1333 offset_intervals (current_buffer, PT, nchars);
1335 intervals = XSTRING (string)->intervals;
1336 /* Get the intervals for the part of the string we are inserting--
1337 not including the combined-before bytes. */
1338 if (nbytes < STRING_BYTES (XSTRING (string)))
1339 intervals = copy_intervals (intervals, pos, nchars);
1341 /* Insert those intervals. */
1342 graft_intervals_into_buffer (intervals, PT, nchars,
1343 current_buffer, inherit);
1346 int pos = PT, pos_byte = PT_BYTE;
1348 adjust_point (nchars + combined_after_bytes,
1349 outgoing_nbytes + combined_after_bytes);
1351 if (combined_after_bytes)
1352 combine_bytes (pos + nchars, pos_byte + outgoing_nbytes,
1353 combined_after_bytes);
1355 if (combined_before_bytes)
1356 combine_bytes (pos, pos_byte, combined_before_bytes);
1360 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
1361 current buffer. If the text in BUF has properties, they are absorbed
1362 into the current buffer.
1364 It does not work to use `insert' for this, because a malloc could happen
1365 and relocate BUF's text before the bcopy happens. */
1367 void
1368 insert_from_buffer (buf, charpos, nchars, inherit)
1369 struct buffer *buf;
1370 int charpos, nchars;
1371 int inherit;
1373 int opoint = PT;
1375 insert_from_buffer_1 (buf, charpos, nchars, inherit);
1376 signal_after_change (opoint, 0, PT - opoint);
1377 update_compositions (opoint, PT, CHECK_BORDER);
1380 static void
1381 insert_from_buffer_1 (buf, from, nchars, inherit)
1382 struct buffer *buf;
1383 int from, nchars;
1384 int inherit;
1386 register Lisp_Object temp;
1387 int chunk, chunk_expanded;
1388 int from_byte = buf_charpos_to_bytepos (buf, from);
1389 int to_byte = buf_charpos_to_bytepos (buf, from + nchars);
1390 int incoming_nbytes = to_byte - from_byte;
1391 int outgoing_nbytes = incoming_nbytes;
1392 int combined_before_bytes, combined_after_bytes;
1393 INTERVAL intervals;
1395 /* Make OUTGOING_NBYTES describe the text
1396 as it will be inserted in this buffer. */
1398 if (NILP (current_buffer->enable_multibyte_characters))
1399 outgoing_nbytes = nchars;
1400 else if (NILP (buf->enable_multibyte_characters))
1402 int outgoing_before_gap = 0;
1403 int outgoing_after_gap = 0;
1405 if (from < BUF_GPT (buf))
1407 chunk = BUF_GPT_BYTE (buf) - from_byte;
1408 if (chunk > incoming_nbytes)
1409 chunk = incoming_nbytes;
1410 outgoing_before_gap
1411 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf, from_byte),
1412 chunk);
1414 else
1415 chunk = 0;
1417 if (chunk < incoming_nbytes)
1418 outgoing_after_gap
1419 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf,
1420 from_byte + chunk),
1421 incoming_nbytes - chunk);
1423 outgoing_nbytes = outgoing_before_gap + outgoing_after_gap;
1426 /* Make sure point-max won't overflow after this insertion. */
1427 XSETINT (temp, outgoing_nbytes + Z);
1428 if (outgoing_nbytes + Z != XINT (temp))
1429 error ("Maximum buffer size exceeded");
1431 /* Do this before moving and increasing the gap,
1432 because the before-change hooks might move the gap
1433 or make it smaller. */
1434 prepare_to_modify_buffer (PT, PT, NULL);
1436 if (PT != GPT)
1437 move_gap_both (PT, PT_BYTE);
1438 if (GAP_SIZE < outgoing_nbytes)
1439 make_gap (outgoing_nbytes - GAP_SIZE);
1441 if (from < BUF_GPT (buf))
1443 chunk = BUF_GPT_BYTE (buf) - from_byte;
1444 if (chunk > incoming_nbytes)
1445 chunk = incoming_nbytes;
1446 /* Record number of output bytes, so we know where
1447 to put the output from the second copy_text. */
1448 chunk_expanded
1449 = copy_text (BUF_BYTE_ADDRESS (buf, from_byte),
1450 GPT_ADDR, chunk,
1451 ! NILP (buf->enable_multibyte_characters),
1452 ! NILP (current_buffer->enable_multibyte_characters));
1454 else
1455 chunk_expanded = chunk = 0;
1457 if (chunk < incoming_nbytes)
1458 copy_text (BUF_BYTE_ADDRESS (buf, from_byte + chunk),
1459 GPT_ADDR + chunk_expanded, incoming_nbytes - chunk,
1460 ! NILP (buf->enable_multibyte_characters),
1461 ! NILP (current_buffer->enable_multibyte_characters));
1463 /* We have copied text into the gap, but we have not altered
1464 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1465 to these functions and get the same results as we would
1466 have got earlier on. Meanwhile, GPT_ADDR does point to
1467 the text that has been stored by copy_text. */
1468 combined_before_bytes
1469 = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1470 combined_after_bytes
1471 = count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1473 unsigned char save = *(GPT_ADDR);
1474 *(GPT_ADDR) = 0;
1475 CHECK_BYTE_COMBINING_FOR_INSERT (PT);
1476 *(GPT_ADDR) = save;
1479 /* Record deletion of the surrounding text that combines with
1480 the insertion. This, together with recording the insertion,
1481 will add up to the right stuff in the undo list.
1483 But there is no need to actually delete the combining bytes
1484 from the buffer and reinsert them. */
1486 if (combined_after_bytes)
1488 Lisp_Object deletion;
1489 deletion = Qnil;
1491 if (! EQ (current_buffer->undo_list, Qt))
1492 deletion = make_buffer_string_both (PT, PT_BYTE,
1493 PT + combined_after_bytes,
1494 PT_BYTE + combined_after_bytes, 1);
1496 adjust_markers_for_record_delete (PT, PT_BYTE,
1497 PT + combined_after_bytes,
1498 PT_BYTE + combined_after_bytes);
1499 if (! EQ (current_buffer->undo_list, Qt))
1500 record_delete (PT, deletion);
1503 if (combined_before_bytes)
1505 Lisp_Object deletion;
1506 deletion = Qnil;
1508 if (! EQ (current_buffer->undo_list, Qt))
1509 deletion = make_buffer_string_both (PT - 1, CHAR_TO_BYTE (PT - 1),
1510 PT, PT_BYTE, 1);
1511 adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
1512 PT, PT_BYTE);
1513 if (! EQ (current_buffer->undo_list, Qt))
1514 record_delete (PT - 1, deletion);
1517 record_insert (PT - !!combined_before_bytes,
1518 nchars - combined_before_bytes + !!combined_before_bytes);
1519 MODIFF++;
1521 GAP_SIZE -= outgoing_nbytes;
1522 GPT += nchars;
1523 ZV += nchars;
1524 Z += nchars;
1525 GPT_BYTE += outgoing_nbytes;
1526 ZV_BYTE += outgoing_nbytes;
1527 Z_BYTE += outgoing_nbytes;
1528 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1530 if (combined_after_bytes)
1531 move_gap_both (GPT + combined_after_bytes,
1532 GPT_BYTE + combined_after_bytes);
1534 if (GPT_BYTE < GPT)
1535 abort ();
1537 adjust_overlays_for_insert (PT, nchars);
1538 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1539 PT_BYTE + outgoing_nbytes,
1540 combined_before_bytes, combined_after_bytes, 0);
1542 if (BUF_INTERVALS (current_buffer) != 0)
1543 offset_intervals (current_buffer, PT, nchars);
1545 /* Get the intervals for the part of the string we are inserting--
1546 not including the combined-before bytes. */
1547 intervals = BUF_INTERVALS (buf);
1548 if (outgoing_nbytes < BUF_Z_BYTE (buf) - BUF_BEG_BYTE (buf))
1549 intervals = copy_intervals (intervals, from, nchars);
1551 /* Insert those intervals. */
1552 graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
1555 int pos = PT, pos_byte = PT_BYTE;
1557 adjust_point (nchars + combined_after_bytes,
1558 outgoing_nbytes + combined_after_bytes);
1560 if (combined_after_bytes)
1561 combine_bytes (pos + nchars, pos_byte + outgoing_nbytes,
1562 combined_after_bytes);
1564 if (combined_before_bytes)
1565 combine_bytes (pos, pos_byte, combined_before_bytes);
1569 /* This function should be called after moving gap to FROM and before
1570 altering text between FROM and TO. This adjusts various position
1571 keepers and markers as if the text is deleted. Don't forget to
1572 call adjust_after_replace after you actually alter the text. */
1574 void
1575 adjust_before_replace (from, from_byte, to, to_byte)
1576 int from, from_byte, to, to_byte;
1578 Lisp_Object deletion;
1580 if (! EQ (current_buffer->undo_list, Qt))
1581 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1583 CHECK_MARKERS ();
1585 adjust_markers_for_delete (from, from_byte, to, to_byte);
1587 if (! EQ (current_buffer->undo_list, Qt))
1588 record_delete (from, deletion);
1590 adjust_overlays_for_delete (from, to - from);
1593 /* Record undo information and adjust markers and position keepers for
1594 a replacement of a text PREV_TEXT at FROM to a new text of LEN
1595 chars (LEN_BYTE bytes) which resides in the gap just after
1596 GPT_ADDR.
1598 PREV_TEXT nil means the new text was just inserted. */
1600 void
1601 adjust_after_replace (from, from_byte, prev_text, len, len_byte)
1602 int from, from_byte, len, len_byte;
1603 Lisp_Object prev_text;
1605 int combined_before_bytes
1606 = count_combining_before (GPT_ADDR, len_byte, from, from_byte);
1607 int combined_after_bytes
1608 = count_combining_after (GPT_ADDR, len_byte, from, from_byte);
1609 /* This flag tells if we combine some bytes with a character before
1610 FROM. This happens even if combined_before_bytes is zero. */
1611 int combine_before = (combined_before_bytes
1612 || (len == 0 && combined_after_bytes));
1614 int nchars_del = 0, nbytes_del = 0;
1616 if (STRINGP (prev_text))
1618 nchars_del = XSTRING (prev_text)->size;
1619 nbytes_del = STRING_BYTES (XSTRING (prev_text));
1622 if ((combine_before && from == BEGV)
1623 || (combined_after_bytes && from == ZV))
1625 /* We can't combine bytes nor signal an error here. So, let's
1626 pretend that the new text is just a single space. */
1627 len = len_byte = 1;
1628 combined_before_bytes = combined_after_bytes = 0;
1629 *(GPT_ADDR) = ' ';
1632 if (combined_after_bytes)
1634 Lisp_Object deletion;
1635 deletion = Qnil;
1637 if (! EQ (current_buffer->undo_list, Qt))
1638 deletion = make_buffer_string_both (from, from_byte,
1639 from + combined_after_bytes,
1640 from_byte + combined_after_bytes,
1643 adjust_markers_for_record_delete (from, from_byte,
1644 from + combined_after_bytes,
1645 from_byte + combined_after_bytes);
1647 if (! EQ (current_buffer->undo_list, Qt))
1648 record_delete (from + nchars_del, deletion);
1651 if (combined_before_bytes
1652 || (len_byte == 0 && combined_after_bytes > 0))
1654 Lisp_Object deletion;
1655 deletion = Qnil;
1657 if (! EQ (current_buffer->undo_list, Qt))
1658 deletion = make_buffer_string_both (from - 1, CHAR_TO_BYTE (from - 1),
1659 from, from_byte, 1);
1660 adjust_markers_for_record_delete (from - 1, CHAR_TO_BYTE (from - 1),
1661 from, from_byte);
1662 if (! EQ (current_buffer->undo_list, Qt))
1663 record_delete (from - 1, deletion);
1666 /* Update various buffer positions for the new text. */
1667 GAP_SIZE -= len_byte;
1668 ZV += len; Z+= len;
1669 ZV_BYTE += len_byte; Z_BYTE += len_byte;
1670 GPT += len; GPT_BYTE += len_byte;
1671 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1673 /* The gap should be at character boundary. */
1674 if (combined_after_bytes)
1675 move_gap_both (GPT + combined_after_bytes,
1676 GPT_BYTE + combined_after_bytes);
1678 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1679 len, len_byte,
1680 combined_before_bytes, combined_after_bytes);
1681 if (! EQ (current_buffer->undo_list, Qt))
1683 if (nchars_del > 0)
1684 record_delete (from - combine_before, prev_text);
1685 if (combine_before)
1686 record_insert (from - 1, len - combined_before_bytes + 1);
1687 else
1688 record_insert (from, len);
1691 if (len > nchars_del)
1692 adjust_overlays_for_insert (from, len - nchars_del);
1693 else if (len < nchars_del)
1694 adjust_overlays_for_delete (from, nchars_del - len);
1695 if (BUF_INTERVALS (current_buffer) != 0)
1697 offset_intervals (current_buffer, from, len - nchars_del);
1701 if (from < PT)
1702 adjust_point (len - nchars_del, len_byte - nbytes_del);
1704 if (combined_after_bytes)
1706 if (combined_before_bytes == len_byte)
1707 /* This is the case that all new bytes are combined. */
1708 combined_before_bytes += combined_after_bytes;
1709 else
1710 combine_bytes (from + len, from_byte + len_byte,
1711 combined_after_bytes);
1713 if (combined_before_bytes)
1714 combine_bytes (from, from_byte, combined_before_bytes);
1717 /* As byte combining will decrease Z, we must check this again. */
1718 if (Z - GPT < END_UNCHANGED)
1719 END_UNCHANGED = Z - GPT;
1721 CHECK_MARKERS ();
1723 if (len == 0)
1724 evaporate_overlays (from);
1725 MODIFF++;
1728 /* Record undo information, adjust markers and position keepers for an
1729 insertion of a text from FROM (FROM_BYTE) to TO (TO_BYTE). The
1730 text already exists in the current buffer but character length (TO
1731 - FROM) may be incorrect, the correct length is NEWLEN. */
1733 void
1734 adjust_after_insert (from, from_byte, to, to_byte, newlen)
1735 int from, from_byte, to, to_byte, newlen;
1737 int len = to - from, len_byte = to_byte - from_byte;
1739 if (GPT != to)
1740 move_gap_both (to, to_byte);
1741 GAP_SIZE += len_byte;
1742 GPT -= len; GPT_BYTE -= len_byte;
1743 ZV -= len; ZV_BYTE -= len_byte;
1744 Z -= len; Z_BYTE -= len_byte;
1745 adjust_after_replace (from, from_byte, Qnil, newlen, len_byte);
1748 /* Replace the text from character positions FROM to TO with NEW,
1749 If PREPARE is nonzero, call prepare_to_modify_buffer.
1750 If INHERIT, the newly inserted text should inherit text properties
1751 from the surrounding non-deleted text. */
1753 /* Note that this does not yet handle markers quite right.
1754 Also it needs to record a single undo-entry that does a replacement
1755 rather than a separate delete and insert.
1756 That way, undo will also handle markers properly.
1758 But if MARKERS is 0, don't relocate markers. */
1760 void
1761 replace_range (from, to, new, prepare, inherit, markers)
1762 Lisp_Object new;
1763 int from, to, prepare, inherit, markers;
1765 int inschars = XSTRING (new)->size;
1766 int insbytes = STRING_BYTES (XSTRING (new));
1767 int from_byte, to_byte;
1768 int nbytes_del, nchars_del;
1769 register Lisp_Object temp;
1770 struct gcpro gcpro1;
1771 int combined_before_bytes, combined_after_bytes;
1772 INTERVAL intervals;
1773 int outgoing_insbytes = insbytes;
1774 Lisp_Object deletion;
1776 CHECK_MARKERS ();
1778 GCPRO1 (new);
1780 if (prepare)
1782 int range_length = to - from;
1783 prepare_to_modify_buffer (from, to, &from);
1784 to = from + range_length;
1787 UNGCPRO;
1789 /* Make args be valid */
1790 if (from < BEGV)
1791 from = BEGV;
1792 if (to > ZV)
1793 to = ZV;
1795 from_byte = CHAR_TO_BYTE (from);
1796 to_byte = CHAR_TO_BYTE (to);
1798 nchars_del = to - from;
1799 nbytes_del = to_byte - from_byte;
1801 if (nbytes_del <= 0 && insbytes == 0)
1802 return;
1804 /* Make OUTGOING_INSBYTES describe the text
1805 as it will be inserted in this buffer. */
1807 if (NILP (current_buffer->enable_multibyte_characters))
1808 outgoing_insbytes = inschars;
1809 else if (! STRING_MULTIBYTE (new))
1810 outgoing_insbytes
1811 = count_size_as_multibyte (XSTRING (new)->data, insbytes);
1813 /* Make sure point-max won't overflow after this insertion. */
1814 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1815 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1816 error ("Maximum buffer size exceeded");
1818 GCPRO1 (new);
1820 /* Make sure the gap is somewhere in or next to what we are deleting. */
1821 if (from > GPT)
1822 gap_right (from, from_byte);
1823 if (to < GPT)
1824 gap_left (to, to_byte, 0);
1826 /* Even if we don't record for undo, we must keep the original text
1827 because we may have to recover it because of inappropriate byte
1828 combining. */
1829 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
1831 if (markers)
1832 /* Relocate all markers pointing into the new, larger gap
1833 to point at the end of the text before the gap.
1834 Do this before recording the deletion,
1835 so that undo handles this after reinserting the text. */
1836 adjust_markers_for_delete (from, from_byte, to, to_byte);
1838 GAP_SIZE += nbytes_del;
1839 ZV -= nchars_del;
1840 Z -= nchars_del;
1841 ZV_BYTE -= nbytes_del;
1842 Z_BYTE -= nbytes_del;
1843 GPT = from;
1844 GPT_BYTE = from_byte;
1845 *(GPT_ADDR) = 0; /* Put an anchor. */
1847 if (GPT_BYTE < GPT)
1848 abort ();
1850 if (GPT - BEG < BEG_UNCHANGED)
1851 BEG_UNCHANGED = GPT - BEG;
1852 if (Z - GPT < END_UNCHANGED)
1853 END_UNCHANGED = Z - GPT;
1855 if (GAP_SIZE < insbytes)
1856 make_gap (insbytes - GAP_SIZE);
1858 /* Copy the string text into the buffer, perhaps converting
1859 between single-byte and multibyte. */
1860 copy_text (XSTRING (new)->data, GPT_ADDR, insbytes,
1861 STRING_MULTIBYTE (new),
1862 ! NILP (current_buffer->enable_multibyte_characters));
1864 /* We have copied text into the gap, but we have not marked
1865 it as part of the buffer. So we can use the old FROM and FROM_BYTE
1866 here, for both the previous text and the following text.
1867 Meanwhile, GPT_ADDR does point to
1868 the text that has been stored by copy_text. */
1870 combined_before_bytes
1871 = count_combining_before (GPT_ADDR, outgoing_insbytes, from, from_byte);
1872 combined_after_bytes
1873 = count_combining_after (GPT_ADDR, outgoing_insbytes, from, from_byte);
1875 if ((combined_before_bytes && from == BEGV)
1876 || (combined_after_bytes && from == ZV))
1878 /* Bytes are being combined across the region boundary. We
1879 should avoid it. We recover the original contents before
1880 signaling an error. */
1881 bcopy (XSTRING (deletion)->data, GPT_ADDR, nbytes_del);
1882 GAP_SIZE -= nbytes_del;
1883 ZV += nchars_del;
1884 Z += nchars_del;
1885 ZV_BYTE += nbytes_del;
1886 Z_BYTE += nbytes_del;
1887 GPT = from + nchars_del;
1888 GPT_BYTE = from_byte + nbytes_del;
1889 *(GPT_ADDR) = 0; /* Put an anchor. */
1890 if (markers)
1891 adjust_markers_for_insert (from, from_byte, to, to_byte, 0, 0, 0);
1892 UNGCPRO;
1893 byte_combining_error ();
1894 GCPRO1 (new);
1897 /* Record deletion of the surrounding text that combines with
1898 the insertion. This, together with recording the insertion,
1899 will add up to the right stuff in the undo list.
1901 But there is no need to actually delete the combining bytes
1902 from the buffer and reinsert them. */
1904 if (combined_after_bytes)
1906 Lisp_Object deletion;
1907 deletion = Qnil;
1909 if (! EQ (current_buffer->undo_list, Qt))
1910 deletion = make_buffer_string_both (from, from_byte,
1911 from + combined_after_bytes,
1912 from_byte + combined_after_bytes,
1915 adjust_markers_for_record_delete (from, from_byte,
1916 from + combined_after_bytes,
1917 from_byte + combined_after_bytes);
1918 if (! EQ (current_buffer->undo_list, Qt))
1919 record_delete (from + nchars_del, deletion);
1922 if (combined_before_bytes)
1924 Lisp_Object deletion;
1925 deletion = Qnil;
1927 if (! EQ (current_buffer->undo_list, Qt))
1928 deletion = make_buffer_string_both (from - 1, CHAR_TO_BYTE (from - 1),
1929 from, from_byte, 1);
1930 adjust_markers_for_record_delete (from - 1, CHAR_TO_BYTE (from - 1),
1931 from, from_byte);
1932 if (! EQ (current_buffer->undo_list, Qt))
1933 record_delete (from - 1, deletion);
1936 if (! EQ (current_buffer->undo_list, Qt))
1938 record_delete (from - !!combined_before_bytes, deletion);
1939 record_insert (from - !!combined_before_bytes,
1940 (inschars - combined_before_bytes
1941 + !!combined_before_bytes));
1944 GAP_SIZE -= outgoing_insbytes;
1945 GPT += inschars;
1946 ZV += inschars;
1947 Z += inschars;
1948 GPT_BYTE += outgoing_insbytes;
1949 ZV_BYTE += outgoing_insbytes;
1950 Z_BYTE += outgoing_insbytes;
1951 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1953 if (combined_after_bytes)
1954 move_gap_both (GPT + combined_after_bytes,
1955 GPT_BYTE + combined_after_bytes);
1957 if (GPT_BYTE < GPT)
1958 abort ();
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);
1963 adjust_overlays_for_insert (from, inschars);
1964 if (markers)
1965 adjust_markers_for_insert (from, from_byte,
1966 from + inschars, from_byte + outgoing_insbytes,
1967 combined_before_bytes, combined_after_bytes, 0);
1969 offset_intervals (current_buffer, from, inschars - nchars_del);
1971 /* Get the intervals for the part of the string we are inserting--
1972 not including the combined-before bytes. */
1973 intervals = XSTRING (new)->intervals;
1974 /* Insert those intervals. */
1975 graft_intervals_into_buffer (intervals, from, inschars,
1976 current_buffer, inherit);
1978 /* Relocate point as if it were a marker. */
1979 if (from < PT)
1980 adjust_point ((from + inschars - (PT < to ? PT : to)),
1981 (from_byte + outgoing_insbytes
1982 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
1984 if (combined_after_bytes)
1986 if (combined_before_bytes == outgoing_insbytes)
1987 /* This is the case that all new bytes are combined. */
1988 combined_before_bytes += combined_after_bytes;
1989 else
1990 combine_bytes (from + inschars, from_byte + outgoing_insbytes,
1991 combined_after_bytes);
1993 if (combined_before_bytes)
1994 combine_bytes (from, from_byte, combined_before_bytes);
1996 /* As byte combining will decrease Z, we must check this again. */
1997 if (Z - GPT < END_UNCHANGED)
1998 END_UNCHANGED = Z - GPT;
2000 if (outgoing_insbytes == 0)
2001 evaporate_overlays (from);
2003 CHECK_MARKERS ();
2005 MODIFF++;
2006 UNGCPRO;
2008 signal_after_change (from, nchars_del, GPT - from);
2009 update_compositions (from, GPT, CHECK_BORDER);
2012 /* Delete characters in current buffer
2013 from FROM up to (but not including) TO.
2014 If TO comes before FROM, we delete nothing. */
2016 void
2017 del_range (from, to)
2018 register int from, to;
2020 del_range_1 (from, to, 1, 0);
2023 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
2024 RET_STRING says to return the deleted text. */
2026 Lisp_Object
2027 del_range_1 (from, to, prepare, ret_string)
2028 int from, to, prepare, ret_string;
2030 int from_byte, to_byte;
2031 Lisp_Object deletion;
2032 struct gcpro gcpro1;
2034 /* Make args be valid */
2035 if (from < BEGV)
2036 from = BEGV;
2037 if (to > ZV)
2038 to = ZV;
2040 if (to <= from)
2041 return Qnil;
2043 if (prepare)
2045 int range_length = to - from;
2046 prepare_to_modify_buffer (from, to, &from);
2047 to = from + range_length;
2050 from_byte = CHAR_TO_BYTE (from);
2051 to_byte = CHAR_TO_BYTE (to);
2053 deletion = del_range_2 (from, from_byte, to, to_byte, ret_string);
2054 GCPRO1(deletion);
2055 signal_after_change (from, to - from, 0);
2056 update_compositions (from, from, CHECK_HEAD);
2057 UNGCPRO;
2058 return deletion;
2061 /* Like del_range_1 but args are byte positions, not char positions. */
2063 void
2064 del_range_byte (from_byte, to_byte, prepare)
2065 int from_byte, to_byte, prepare;
2067 int from, to;
2069 /* Make args be valid */
2070 if (from_byte < BEGV_BYTE)
2071 from_byte = BEGV_BYTE;
2072 if (to_byte > ZV_BYTE)
2073 to_byte = ZV_BYTE;
2075 if (to_byte <= from_byte)
2076 return;
2078 from = BYTE_TO_CHAR (from_byte);
2079 to = BYTE_TO_CHAR (to_byte);
2081 if (prepare)
2083 int old_from = from, old_to = Z - to;
2084 int range_length = to - from;
2085 prepare_to_modify_buffer (from, to, &from);
2086 to = from + range_length;
2088 if (old_from != from)
2089 from_byte = CHAR_TO_BYTE (from);
2090 if (old_to == Z - to)
2091 to_byte = CHAR_TO_BYTE (to);
2094 del_range_2 (from, from_byte, to, to_byte, 0);
2095 signal_after_change (from, to - from, 0);
2096 update_compositions (from, from, CHECK_HEAD);
2099 /* Like del_range_1, but positions are specified both as charpos
2100 and bytepos. */
2102 void
2103 del_range_both (from, from_byte, to, to_byte, prepare)
2104 int from, from_byte, to, to_byte, prepare;
2106 /* Make args be valid */
2107 if (from_byte < BEGV_BYTE)
2108 from_byte = BEGV_BYTE;
2109 if (to_byte > ZV_BYTE)
2110 to_byte = ZV_BYTE;
2112 if (to_byte <= from_byte)
2113 return;
2115 if (from < BEGV)
2116 from = BEGV;
2117 if (to > ZV)
2118 to = ZV;
2120 if (prepare)
2122 int old_from = from, old_to = Z - to;
2123 int range_length = to - from;
2124 prepare_to_modify_buffer (from, to, &from);
2125 to = from + range_length;
2127 if (old_from != from)
2128 from_byte = CHAR_TO_BYTE (from);
2129 if (old_to == Z - to)
2130 to_byte = CHAR_TO_BYTE (to);
2133 del_range_2 (from, from_byte, to, to_byte, 0);
2134 signal_after_change (from, to - from, 0);
2135 update_compositions (from, from, CHECK_HEAD);
2138 /* Delete a range of text, specified both as character positions
2139 and byte positions. FROM and TO are character positions,
2140 while FROM_BYTE and TO_BYTE are byte positions.
2141 If RET_STRING is true, the deleted area is returned as a string. */
2143 Lisp_Object
2144 del_range_2 (from, from_byte, to, to_byte, ret_string)
2145 int from, from_byte, to, to_byte, ret_string;
2147 register int nbytes_del, nchars_del;
2148 int combined_after_bytes;
2149 Lisp_Object deletion;
2150 int from_byte_1;
2152 CHECK_MARKERS ();
2154 nchars_del = to - from;
2155 nbytes_del = to_byte - from_byte;
2157 /* Make sure the gap is somewhere in or next to what we are deleting. */
2158 if (from > GPT)
2159 gap_right (from, from_byte);
2160 if (to < GPT)
2161 gap_left (to, to_byte, 0);
2163 combined_after_bytes
2164 = count_combining_before (BUF_BYTE_ADDRESS (current_buffer, to_byte),
2165 Z_BYTE - to_byte, from, from_byte);
2166 if (combined_after_bytes)
2168 if (from == BEGV || to == ZV)
2169 byte_combining_error ();
2170 from_byte_1 = from_byte;
2171 DEC_POS (from_byte_1);
2173 else
2174 from_byte_1 = from_byte;
2176 if (ret_string || ! EQ (current_buffer->undo_list, Qt))
2177 deletion
2178 = make_buffer_string_both (from - !!combined_after_bytes,
2179 from_byte_1,
2180 to + combined_after_bytes,
2181 to_byte + combined_after_bytes, 1);
2182 else
2183 deletion = Qnil;
2185 if (combined_after_bytes)
2186 /* COMBINED_AFTER_BYTES nonzero means that the above code moved
2187 the gap. We must move the gap again to a proper place. */
2188 move_gap_both (from, from_byte);
2190 /* Relocate all markers pointing into the new, larger gap
2191 to point at the end of the text before the gap.
2192 Do this before recording the deletion,
2193 so that undo handles this after reinserting the text. */
2194 adjust_markers_for_delete (from, from_byte, to, to_byte);
2195 if (combined_after_bytes)
2197 /* Adjust markers for the phony deletion
2198 that we are about to call record_undo for. */
2200 /* Here we delete the markers that formerly
2201 pointed at TO ... TO + COMBINED_AFTER_BYTES.
2202 But because of the call to adjust_markers_for_delete, above,
2203 they now point at FROM ... FROM + COMBINED_AFTER_BYTES. */
2204 adjust_markers_for_record_delete (from, from_byte,
2205 from + combined_after_bytes,
2206 from_byte + combined_after_bytes);
2208 adjust_markers_for_record_delete (from - 1, from_byte_1,
2209 from, from_byte);
2211 if (! EQ (current_buffer->undo_list, Qt))
2212 record_delete (from - !!combined_after_bytes, deletion);
2213 MODIFF++;
2215 /* Relocate point as if it were a marker. */
2216 if (from < PT)
2217 adjust_point (from - (PT < to ? PT : to),
2218 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte));
2220 offset_intervals (current_buffer, from, - nchars_del);
2222 /* Adjust the overlay center as needed. This must be done after
2223 adjusting the markers that bound the overlays. */
2224 adjust_overlays_for_delete (from, nchars_del);
2226 GAP_SIZE += nbytes_del;
2227 ZV_BYTE -= nbytes_del;
2228 Z_BYTE -= nbytes_del;
2229 ZV -= nchars_del;
2230 Z -= nchars_del;
2231 GPT = from;
2232 GPT_BYTE = from_byte;
2234 if (combined_after_bytes)
2235 move_gap_both (GPT + combined_after_bytes,
2236 GPT_BYTE + combined_after_bytes);
2238 *(GPT_ADDR) = 0; /* Put an anchor. */
2240 if (GPT_BYTE < GPT)
2241 abort ();
2243 if (GPT - BEG < BEG_UNCHANGED)
2244 BEG_UNCHANGED = GPT - BEG;
2245 if (Z - GPT < END_UNCHANGED)
2246 END_UNCHANGED = Z - GPT;
2248 if (combined_after_bytes)
2250 /* Adjust markers for byte combining. As we have already
2251 adjuted markers without concerning byte combining, here we
2252 must concern only byte combining. */
2253 adjust_markers_for_replace (from, from_byte, 0, 0, 0, 0,
2254 0, combined_after_bytes);
2255 combine_bytes (from, from_byte, combined_after_bytes);
2257 record_insert (GPT - 1, 1);
2259 if (Z - GPT < END_UNCHANGED)
2260 END_UNCHANGED = Z - GPT;
2263 CHECK_MARKERS ();
2265 evaporate_overlays (from);
2267 return deletion;
2270 /* Call this if you're about to change the region of BUFFER from
2271 character positions START to END. This checks the read-only
2272 properties of the region, calls the necessary modification hooks,
2273 and warns the next redisplay that it should pay attention to that
2274 area. */
2276 void
2277 modify_region (buffer, start, end)
2278 struct buffer *buffer;
2279 int start, end;
2281 struct buffer *old_buffer = current_buffer;
2283 if (buffer != old_buffer)
2284 set_buffer_internal (buffer);
2286 prepare_to_modify_buffer (start, end, NULL);
2288 BUF_COMPUTE_UNCHANGED (buffer, start - 1, end);
2290 if (MODIFF <= SAVE_MODIFF)
2291 record_first_change ();
2292 MODIFF++;
2294 buffer->point_before_scroll = Qnil;
2296 if (buffer != old_buffer)
2297 set_buffer_internal (old_buffer);
2300 /* Check that it is okay to modify the buffer between START and END,
2301 which are char positions.
2303 Run the before-change-function, if any. If intervals are in use,
2304 verify that the text to be modified is not read-only, and call
2305 any modification properties the text may have.
2307 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2308 by holding its value temporarily in a marker. */
2310 void
2311 prepare_to_modify_buffer (start, end, preserve_ptr)
2312 int start, end;
2313 int *preserve_ptr;
2315 if (!NILP (current_buffer->read_only))
2316 Fbarf_if_buffer_read_only ();
2318 /* Let redisplay consider other windows than selected_window
2319 if modifying another buffer. */
2320 if (XBUFFER (XWINDOW (selected_window)->buffer) != current_buffer)
2321 ++windows_or_buffers_changed;
2323 if (BUF_INTERVALS (current_buffer) != 0)
2325 if (preserve_ptr)
2327 Lisp_Object preserve_marker;
2328 struct gcpro gcpro1;
2329 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
2330 GCPRO1 (preserve_marker);
2331 verify_interval_modification (current_buffer, start, end);
2332 *preserve_ptr = marker_position (preserve_marker);
2333 unchain_marker (preserve_marker);
2334 UNGCPRO;
2336 else
2337 verify_interval_modification (current_buffer, start, end);
2340 #ifdef CLASH_DETECTION
2341 if (!NILP (current_buffer->file_truename)
2342 /* Make binding buffer-file-name to nil effective. */
2343 && !NILP (current_buffer->filename)
2344 && SAVE_MODIFF >= MODIFF)
2345 lock_file (current_buffer->file_truename);
2346 #else
2347 /* At least warn if this file has changed on disk since it was visited. */
2348 if (!NILP (current_buffer->filename)
2349 && SAVE_MODIFF >= MODIFF
2350 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
2351 && !NILP (Ffile_exists_p (current_buffer->filename)))
2352 call1 (intern ("ask-user-about-supersession-threat"),
2353 current_buffer->filename);
2354 #endif /* not CLASH_DETECTION */
2356 signal_before_change (start, end, preserve_ptr);
2358 if (current_buffer->newline_cache)
2359 invalidate_region_cache (current_buffer,
2360 current_buffer->newline_cache,
2361 start - BEG, Z - end);
2362 if (current_buffer->width_run_cache)
2363 invalidate_region_cache (current_buffer,
2364 current_buffer->width_run_cache,
2365 start - BEG, Z - end);
2367 Vdeactivate_mark = Qt;
2370 /* These macros work with an argument named `preserve_ptr'
2371 and a local variable named `preserve_marker'. */
2373 #define PRESERVE_VALUE \
2374 if (preserve_ptr && NILP (preserve_marker)) \
2375 preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
2377 #define RESTORE_VALUE \
2378 if (! NILP (preserve_marker)) \
2380 *preserve_ptr = marker_position (preserve_marker); \
2381 unchain_marker (preserve_marker); \
2384 #define PRESERVE_START_END \
2385 if (NILP (start_marker)) \
2386 start_marker = Fcopy_marker (start, Qnil); \
2387 if (NILP (end_marker)) \
2388 end_marker = Fcopy_marker (end, Qnil);
2390 #define FETCH_START \
2391 (! NILP (start_marker) ? Fmarker_position (start_marker) : start)
2393 #define FETCH_END \
2394 (! NILP (end_marker) ? Fmarker_position (end_marker) : end)
2396 /* Signal a change to the buffer immediately before it happens.
2397 START_INT and END_INT are the bounds of the text to be changed.
2399 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
2400 by holding its value temporarily in a marker. */
2402 void
2403 signal_before_change (start_int, end_int, preserve_ptr)
2404 int start_int, end_int;
2405 int *preserve_ptr;
2407 Lisp_Object start, end;
2408 Lisp_Object start_marker, end_marker;
2409 Lisp_Object preserve_marker;
2410 struct gcpro gcpro1, gcpro2, gcpro3;
2412 if (inhibit_modification_hooks)
2413 return;
2415 start = make_number (start_int);
2416 end = make_number (end_int);
2417 preserve_marker = Qnil;
2418 start_marker = Qnil;
2419 end_marker = Qnil;
2420 GCPRO3 (preserve_marker, start_marker, end_marker);
2422 /* If buffer is unmodified, run a special hook for that case. */
2423 if (SAVE_MODIFF >= MODIFF
2424 && !NILP (Vfirst_change_hook)
2425 && !NILP (Vrun_hooks))
2427 PRESERVE_VALUE;
2428 PRESERVE_START_END;
2429 call1 (Vrun_hooks, Qfirst_change_hook);
2432 /* Run the before-change-function if any.
2433 We don't bother "binding" this variable to nil
2434 because it is obsolete anyway and new code should not use it. */
2435 if (!NILP (Vbefore_change_function))
2437 PRESERVE_VALUE;
2438 PRESERVE_START_END;
2439 call2 (Vbefore_change_function, FETCH_START, FETCH_END);
2442 /* Now run the before-change-functions if any. */
2443 if (!NILP (Vbefore_change_functions))
2445 Lisp_Object args[3];
2446 Lisp_Object before_change_functions;
2447 Lisp_Object after_change_functions;
2448 struct gcpro gcpro1, gcpro2;
2450 PRESERVE_VALUE;
2451 PRESERVE_START_END;
2453 /* "Bind" before-change-functions and after-change-functions
2454 to nil--but in a way that errors don't know about.
2455 That way, if there's an error in them, they will stay nil. */
2456 before_change_functions = Vbefore_change_functions;
2457 after_change_functions = Vafter_change_functions;
2458 Vbefore_change_functions = Qnil;
2459 Vafter_change_functions = Qnil;
2460 GCPRO2 (before_change_functions, after_change_functions);
2462 /* Actually run the hook functions. */
2463 args[0] = Qbefore_change_functions;
2464 args[1] = FETCH_START;
2465 args[2] = FETCH_END;
2466 run_hook_list_with_args (before_change_functions, 3, args);
2468 /* "Unbind" the variables we "bound" to nil. */
2469 Vbefore_change_functions = before_change_functions;
2470 Vafter_change_functions = after_change_functions;
2471 UNGCPRO;
2474 if (!NILP (current_buffer->overlays_before)
2475 || !NILP (current_buffer->overlays_after))
2477 PRESERVE_VALUE;
2478 report_overlay_modification (FETCH_START, FETCH_END, 0,
2479 FETCH_START, FETCH_END, Qnil);
2482 if (! NILP (start_marker))
2483 free_marker (start_marker);
2484 if (! NILP (end_marker))
2485 free_marker (end_marker);
2486 RESTORE_VALUE;
2487 UNGCPRO;
2490 /* Signal a change immediately after it happens.
2491 CHARPOS is the character position of the start of the changed text.
2492 LENDEL is the number of characters of the text before the change.
2493 (Not the whole buffer; just the part that was changed.)
2494 LENINS is the number of characters in that part of the text
2495 after the change. */
2497 void
2498 signal_after_change (charpos, lendel, lenins)
2499 int charpos, lendel, lenins;
2501 if (inhibit_modification_hooks)
2502 return;
2504 /* If we are deferring calls to the after-change functions
2505 and there are no before-change functions,
2506 just record the args that we were going to use. */
2507 if (! NILP (Vcombine_after_change_calls)
2508 && NILP (Vbefore_change_function) && NILP (Vbefore_change_functions)
2509 && NILP (current_buffer->overlays_before)
2510 && NILP (current_buffer->overlays_after))
2512 Lisp_Object elt;
2514 if (!NILP (combine_after_change_list)
2515 && current_buffer != XBUFFER (combine_after_change_buffer))
2516 Fcombine_after_change_execute ();
2518 elt = Fcons (make_number (charpos - BEG),
2519 Fcons (make_number (Z - (charpos - lendel + lenins)),
2520 Fcons (make_number (lenins - lendel), Qnil)));
2521 combine_after_change_list
2522 = Fcons (elt, combine_after_change_list);
2523 combine_after_change_buffer = Fcurrent_buffer ();
2525 return;
2528 if (!NILP (combine_after_change_list))
2529 Fcombine_after_change_execute ();
2531 /* Run the after-change-function if any.
2532 We don't bother "binding" this variable to nil
2533 because it is obsolete anyway and new code should not use it. */
2534 if (!NILP (Vafter_change_function))
2535 call3 (Vafter_change_function,
2536 make_number (charpos), make_number (charpos + lenins),
2537 make_number (lendel));
2539 if (!NILP (Vafter_change_functions))
2541 Lisp_Object args[4];
2542 Lisp_Object before_change_functions;
2543 Lisp_Object after_change_functions;
2544 struct gcpro gcpro1, gcpro2;
2546 /* "Bind" before-change-functions and after-change-functions
2547 to nil--but in a way that errors don't know about.
2548 That way, if there's an error in them, they will stay nil. */
2549 before_change_functions = Vbefore_change_functions;
2550 after_change_functions = Vafter_change_functions;
2551 Vbefore_change_functions = Qnil;
2552 Vafter_change_functions = Qnil;
2553 GCPRO2 (before_change_functions, after_change_functions);
2555 /* Actually run the hook functions. */
2556 args[0] = Qafter_change_functions;
2557 XSETFASTINT (args[1], charpos);
2558 XSETFASTINT (args[2], charpos + lenins);
2559 XSETFASTINT (args[3], lendel);
2560 run_hook_list_with_args (after_change_functions,
2561 4, args);
2563 /* "Unbind" the variables we "bound" to nil. */
2564 Vbefore_change_functions = before_change_functions;
2565 Vafter_change_functions = after_change_functions;
2566 UNGCPRO;
2569 if (!NILP (current_buffer->overlays_before)
2570 || !NILP (current_buffer->overlays_after))
2571 report_overlay_modification (make_number (charpos),
2572 make_number (charpos + lenins),
2574 make_number (charpos),
2575 make_number (charpos + lenins),
2576 make_number (lendel));
2578 /* After an insertion, call the text properties
2579 insert-behind-hooks or insert-in-front-hooks. */
2580 if (lendel == 0)
2581 report_interval_modification (make_number (charpos),
2582 make_number (charpos + lenins));
2585 Lisp_Object
2586 Fcombine_after_change_execute_1 (val)
2587 Lisp_Object val;
2589 Vcombine_after_change_calls = val;
2590 return val;
2593 DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
2594 Scombine_after_change_execute, 0, 0, 0,
2595 "This function is for use internally in `combine-after-change-calls'.")
2598 int count = specpdl_ptr - specpdl;
2599 int beg, end, change;
2600 int begpos, endpos;
2601 Lisp_Object tail;
2603 if (NILP (combine_after_change_list))
2604 return Qnil;
2606 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
2608 Fset_buffer (combine_after_change_buffer);
2610 /* # chars unchanged at beginning of buffer. */
2611 beg = Z - BEG;
2612 /* # chars unchanged at end of buffer. */
2613 end = beg;
2614 /* Total amount of insertion (negative for deletion). */
2615 change = 0;
2617 /* Scan the various individual changes,
2618 accumulating the range info in BEG, END and CHANGE. */
2619 for (tail = combine_after_change_list; CONSP (tail);
2620 tail = XCDR (tail))
2622 Lisp_Object elt;
2623 int thisbeg, thisend, thischange;
2625 /* Extract the info from the next element. */
2626 elt = XCAR (tail);
2627 if (! CONSP (elt))
2628 continue;
2629 thisbeg = XINT (XCAR (elt));
2631 elt = XCDR (elt);
2632 if (! CONSP (elt))
2633 continue;
2634 thisend = XINT (XCAR (elt));
2636 elt = XCDR (elt);
2637 if (! CONSP (elt))
2638 continue;
2639 thischange = XINT (XCAR (elt));
2641 /* Merge this range into the accumulated range. */
2642 change += thischange;
2643 if (thisbeg < beg)
2644 beg = thisbeg;
2645 if (thisend < end)
2646 end = thisend;
2649 /* Get the current start and end positions of the range
2650 that was changed. */
2651 begpos = BEG + beg;
2652 endpos = Z - end;
2654 /* We are about to handle these, so discard them. */
2655 combine_after_change_list = Qnil;
2657 /* Now run the after-change functions for real.
2658 Turn off the flag that defers them. */
2659 record_unwind_protect (Fcombine_after_change_execute_1,
2660 Vcombine_after_change_calls);
2661 signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
2662 update_compositions (begpos, endpos, CHECK_ALL);
2664 return unbind_to (count, Qnil);
2667 void
2668 syms_of_insdel ()
2670 staticpro (&combine_after_change_list);
2671 combine_after_change_list = Qnil;
2672 combine_after_change_buffer = Qnil;
2674 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag,
2675 "Non-nil means enable debugging checks for invalid marker positions.");
2676 check_markers_debug_flag = 0;
2677 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
2678 "Used internally by the `combine-after-change-calls' macro.");
2679 Vcombine_after_change_calls = Qnil;
2681 DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks,
2682 "Non-nil means don't run any of the hooks that respond to buffer changes.\n\
2683 This affects `before-change-functions' and `after-change-functions',\n\
2684 as well as hooks attached to text properties and overlays.");
2685 inhibit_modification_hooks = 0;
2687 defsubr (&Scombine_after_change_execute);