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