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