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