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