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