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