Merge from trunk
[bpt/emacs.git] / src / insdel.c
CommitLineData
b45433b3 1/* Buffer insertion/deletion and gap motion for GNU Emacs.
0b5538bd 2 Copyright (C) 1985, 1986, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
114f9c96 3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
8cabe764 4 Free Software Foundation, Inc.
b45433b3
JB
5
6This file is part of GNU Emacs.
7
9ec0b715 8GNU Emacs is free software: you can redistribute it and/or modify
b45433b3 9it under the terms of the GNU General Public License as published by
9ec0b715
GM
10the Free Software Foundation, either version 3 of the License, or
11(at your option) any later version.
b45433b3
JB
12
13GNU Emacs is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
9ec0b715 19along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
b45433b3
JB
20
21
18160b98 22#include <config.h>
d7306fe6 23#include <setjmp.h>
b45433b3 24#include "lisp.h"
679194a6 25#include "intervals.h"
b45433b3 26#include "buffer.h"
811f7370 27#include "character.h"
b45433b3 28#include "window.h"
d014bf88 29#include "blockinput.h"
dfcf069d 30#include "region-cache.h"
b45433b3 31
d206af14
RS
32#ifndef NULL
33#define NULL 0
34#endif
35
ae19ba7c
SM
36static 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);
40static void insert_from_buffer_1 (struct buffer *buf,
41 EMACS_INT from, EMACS_INT nchars,
42 int inherit);
43static void gap_left (EMACS_INT charpos, EMACS_INT bytepos, int newgap);
44static void gap_right (EMACS_INT charpos, EMACS_INT bytepos);
45static void adjust_markers_gap_motion (EMACS_INT from, EMACS_INT to,
46 EMACS_INT amount);
47static void adjust_markers_for_insert (EMACS_INT from, EMACS_INT from_byte,
48 EMACS_INT to, EMACS_INT to_byte,
49 int before_markers);
50static void adjust_markers_for_replace (EMACS_INT, EMACS_INT, EMACS_INT,
51 EMACS_INT, EMACS_INT, EMACS_INT);
52static void adjust_point (EMACS_INT nchars, EMACS_INT nbytes);
395ec62e 53
971de7fb 54Lisp_Object Fcombine_after_change_execute (void);
fb2e7d14
RS
55
56/* Non-nil means don't call the after-change-functions right away,
ce5b453a 57 just record an element in combine_after_change_list. */
fb2e7d14
RS
58Lisp_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). */
70Lisp_Object combine_after_change_list;
71
72/* Buffer which combine_after_change_list is about. */
73Lisp_Object combine_after_change_buffer;
27ea0af2
GM
74
75Lisp_Object Qinhibit_modification_hooks;
2b083808 76\f
60ea6052
RS
77/* Check all markers in the current buffer, looking for something invalid. */
78
79static int check_markers_debug_flag;
80
81#define CHECK_MARKERS() \
82 if (check_markers_debug_flag) \
83 check_markers (); \
84 else
85
86void
971de7fb 87check_markers (void)
60ea6052 88{
dab0b04d 89 register struct Lisp_Marker *tail;
9f3ede3c 90 int multibyte = ! NILP (current_buffer->enable_multibyte_characters);
60ea6052 91
dab0b04d 92 for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
60ea6052 93 {
dab0b04d 94 if (tail->buffer->text != current_buffer->text)
60ea6052 95 abort ();
dab0b04d 96 if (tail->charpos > Z)
60ea6052 97 abort ();
dab0b04d 98 if (tail->bytepos > Z_BYTE)
60ea6052 99 abort ();
dab0b04d 100 if (multibyte && ! CHAR_HEAD_P (FETCH_BYTE (tail->bytepos)))
9f3ede3c 101 abort ();
60ea6052
RS
102 }
103}
104\f
3be11131 105/* Move gap to position CHARPOS.
b45433b3
JB
106 Note that this can quit! */
107
c660b094 108void
ae19ba7c 109move_gap (EMACS_INT charpos)
b45433b3 110{
3be11131 111 move_gap_both (charpos, charpos_to_bytepos (charpos));
b45433b3
JB
112}
113
3be11131
RS
114/* Move gap to byte position BYTEPOS, which is also char position CHARPOS.
115 Note that this can quit! */
116
117void
ae19ba7c 118move_gap_both (EMACS_INT charpos, EMACS_INT bytepos)
3be11131
RS
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.
b45433b3
JB
129 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
130
2bcaed71 131static void
ae19ba7c 132gap_left (EMACS_INT charpos, EMACS_INT bytepos, int newgap)
b45433b3
JB
133{
134 register unsigned char *to, *from;
ae19ba7c
SM
135 register EMACS_INT i;
136 EMACS_INT new_s1;
b45433b3 137
b45433b3 138 if (!newgap)
a50df55b 139 BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
b45433b3 140
3be11131 141 i = GPT_BYTE;
b45433b3
JB
142 to = GAP_END_ADDR;
143 from = GPT_ADDR;
3be11131 144 new_s1 = GPT_BYTE;
b45433b3
JB
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. */
3be11131 152 i = new_s1 - bytepos;
b45433b3
JB
153 if (i == 0)
154 break;
155 /* If a quit is requested, stop copying now.
3be11131 156 Change BYTEPOS to be where we have actually moved the gap to. */
b45433b3
JB
157 if (QUITP)
158 {
3be11131
RS
159 bytepos = new_s1;
160 charpos = BYTE_TO_CHAR (bytepos);
b45433b3
JB
161 break;
162 }
163 /* Move at most 32000 chars before checking again for a quit. */
164 if (i > 32000)
165 i = 32000;
72af86bd
AS
166 new_s1 -= i;
167 from -= i, to -= i;
168 memmove (to, from, i);
b45433b3
JB
169 }
170
3be11131
RS
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
b45433b3 173 or may be where a quit was detected. */
3be11131
RS
174 adjust_markers_gap_motion (bytepos, GPT_BYTE, GAP_SIZE);
175 GPT_BYTE = bytepos;
176 GPT = charpos;
177 if (bytepos < charpos)
178 abort ();
469ff680 179 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
b45433b3
JB
180 QUIT;
181}
182
2b34df4e 183/* Move the gap to a position greater than the current GPT.
3be11131
RS
184 BYTEPOS describes the new position as a byte position,
185 and CHARPOS is the corresponding char position. */
186
2bcaed71 187static void
ae19ba7c 188gap_right (EMACS_INT charpos, EMACS_INT bytepos)
b45433b3
JB
189{
190 register unsigned char *to, *from;
ae19ba7c
SM
191 register EMACS_INT i;
192 EMACS_INT new_s1;
b45433b3 193
a50df55b 194 BUF_COMPUTE_UNCHANGED (current_buffer, charpos, GPT);
b45433b3 195
3be11131 196 i = GPT_BYTE;
b45433b3
JB
197 from = GAP_END_ADDR;
198 to = GPT_ADDR;
3be11131 199 new_s1 = GPT_BYTE;
b45433b3
JB
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. */
3be11131 207 i = bytepos - new_s1;
b45433b3
JB
208 if (i == 0)
209 break;
210 /* If a quit is requested, stop copying now.
3be11131 211 Change BYTEPOS to be where we have actually moved the gap to. */
b45433b3
JB
212 if (QUITP)
213 {
3be11131
RS
214 bytepos = new_s1;
215 charpos = BYTE_TO_CHAR (bytepos);
b45433b3
JB
216 break;
217 }
218 /* Move at most 32000 chars before checking again for a quit. */
219 if (i > 32000)
220 i = 32000;
72af86bd
AS
221 new_s1 += i;
222 memmove (to, from, i);
223 from += i, to += i;
b45433b3
JB
224 }
225
3be11131
RS
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 ();
469ff680 232 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
b45433b3
JB
233 QUIT;
234}
2b083808 235\f
3be11131
RS
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).
8948d317 238
b45433b3
JB
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
8948d317
RS
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
3be11131
RS
245 deletion.)
246
247 The markers' character positions are not altered,
248 because gap motion does not affect character positions. */
249
250int adjust_markers_test;
b45433b3 251
2bcaed71 252static void
ae19ba7c 253adjust_markers_gap_motion (EMACS_INT from, EMACS_INT to, EMACS_INT amount)
b45433b3 254{
80f6e77c
RS
255 /* Now that a marker has a bytepos, not counting the gap,
256 nothing needs to be done here. */
257#if 0
b45433b3
JB
258 Lisp_Object marker;
259 register struct Lisp_Marker *m;
ae19ba7c 260 register EMACS_INT mpos;
b45433b3 261
9fbf87cd 262 marker = BUF_MARKERS (current_buffer);
b45433b3 263
d427b66a 264 while (!NILP (marker))
b45433b3
JB
265 {
266 m = XMARKER (marker);
80f6e77c 267 mpos = m->bytepos;
b45433b3
JB
268 if (amount > 0)
269 {
270 if (mpos > to && mpos < to + amount)
3be11131
RS
271 {
272 if (adjust_markers_test)
273 abort ();
274 mpos = to + amount;
275 }
b45433b3
JB
276 }
277 else
278 {
8948d317
RS
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. */
b45433b3 282 if (mpos > from + amount && mpos <= from)
8948d317 283 {
3be11131
RS
284 if (adjust_markers_test)
285 abort ();
286 mpos = from + amount;
8948d317 287 }
b45433b3
JB
288 }
289 if (mpos > from && mpos <= to)
290 mpos += amount;
291 m->bufpos = mpos;
292 marker = m->chain;
293 }
80f6e77c 294#endif
b45433b3 295}
2b083808 296\f
3be11131
RS
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. */
beecb55b 303
809f3d51 304void
ae19ba7c
SM
305adjust_markers_for_delete (EMACS_INT from, EMACS_INT from_byte,
306 EMACS_INT to, EMACS_INT to_byte)
3be11131
RS
307{
308 Lisp_Object marker;
309 register struct Lisp_Marker *m;
ae19ba7c 310 register EMACS_INT charpos;
3be11131 311
dab0b04d 312 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
3be11131 313 {
3be11131
RS
314 charpos = m->charpos;
315
316 if (charpos > Z)
317 abort ();
318
319 /* If the marker is after the deletion,
80f6e77c 320 relocate by number of chars / bytes deleted. */
3be11131 321 if (charpos > to)
80f6e77c
RS
322 {
323 m->charpos -= to - from;
324 m->bytepos -= to_byte - from_byte;
325 }
80f6e77c 326 /* Here's the case where a marker is inside text being deleted. */
3be11131
RS
327 else if (charpos > from)
328 {
00de2987 329 if (! m->insertion_type)
dab0b04d 330 { /* Normal markers will end up at the beginning of the
00de2987 331 re-inserted text after undoing a deletion, and must be
177c0ea7 332 adjusted to move them to the correct place. */
dab0b04d 333 XSETMISC (marker, m);
28259cac 334 record_marker_adjustment (marker, from - charpos);
dab0b04d 335 }
00de2987 336 else if (charpos < to)
dab0b04d 337 { /* Before-insertion markers will automatically move forward
00de2987
MB
338 upon re-inserting the deleted text, so we have to arrange
339 for them to move backward to the correct position. */
dab0b04d 340 XSETMISC (marker, m);
28259cac 341 record_marker_adjustment (marker, to - charpos);
dab0b04d 342 }
3be11131 343 m->charpos = from;
80f6e77c 344 m->bytepos = from_byte;
3be11131 345 }
00de2987
MB
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. */
dab0b04d 354 XSETMISC (marker, m);
00de2987
MB
355 record_marker_adjustment (marker, to - from);
356 }
3be11131
RS
357 }
358}
23b20a70 359
2b083808 360\f
432f78d2
RS
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).
3be11131 364
3be11131
RS
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
369static void
ae19ba7c
SM
370adjust_markers_for_insert (EMACS_INT from, EMACS_INT from_byte,
371 EMACS_INT to, EMACS_INT to_byte, int before_markers)
beecb55b 372{
dab0b04d 373 struct Lisp_Marker *m;
469ff680 374 int adjusted = 0;
ae19ba7c
SM
375 EMACS_INT nchars = to - from;
376 EMACS_INT nbytes = to_byte - from_byte;
beecb55b 377
dab0b04d 378 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
beecb55b 379 {
86a56ef3
SM
380 eassert (m->bytepos >= m->charpos
381 && m->bytepos - m->charpos <= Z_BYTE - Z);
1f90a790 382
432f78d2 383 if (m->bytepos == from_byte)
469ff680 384 {
432f78d2
RS
385 if (m->insertion_type || before_markers)
386 {
b16afa45
KH
387 m->bytepos = to_byte;
388 m->charpos = to;
432f78d2
RS
389 if (m->insertion_type)
390 adjusted = 1;
391 }
ce97a2d7 392 }
80f6e77c
RS
393 else if (m->bytepos > from_byte)
394 {
395 m->bytepos += nbytes;
b16afa45 396 m->charpos += nchars;
80f6e77c 397 }
beecb55b 398 }
3be11131
RS
399
400 /* Adjusting only markers whose insertion-type is t may result in
409f2919 401 - disordered start and end in overlays, and
6b61353c 402 - disordered overlays in the slot `overlays_before' of current_buffer. */
469ff680 403 if (adjusted)
6b61353c
KH
404 {
405 fix_start_end_in_overlays(from, to);
406 fix_overlays_before (current_buffer, from, to);
407 }
beecb55b
RS
408}
409
3be11131
RS
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
a27a38d8 420static void
ae19ba7c 421adjust_point (EMACS_INT nchars, EMACS_INT nbytes)
a27a38d8 422{
3be11131
RS
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. */
86a56ef3 427 eassert (PT_BYTE >= PT && PT_BYTE - PT <= ZV_BYTE - ZV);
a27a38d8 428}
b45433b3 429\f
652838b5
KH
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
adee4f91
KH
432 (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
433 an insertion. */
652838b5
KH
434
435static void
ae19ba7c
SM
436adjust_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)
652838b5 439{
dab0b04d 440 register struct Lisp_Marker *m;
ae19ba7c
SM
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;
652838b5 444
dab0b04d 445 for (m = BUF_MARKERS (current_buffer); m; m = m->next)
652838b5 446 {
adee4f91 447 if (m->bytepos >= prev_to_byte)
652838b5 448 {
adee4f91
KH
449 m->charpos += diff_chars;
450 m->bytepos += diff_bytes;
652838b5 451 }
adee4f91 452 else if (m->bytepos > from_byte)
652838b5 453 {
652838b5 454 m->charpos = from;
b16afa45 455 m->bytepos = from_byte;
652838b5 456 }
652838b5 457 }
3019692c
KH
458
459 CHECK_MARKERS ();
652838b5
KH
460}
461
462\f
3be11131 463/* Make the gap NBYTES_ADDED bytes longer. */
b45433b3 464
c660b094 465void
ae19ba7c 466make_gap_larger (EMACS_INT nbytes_added)
b45433b3 467{
b45433b3 468 Lisp_Object tem;
ae19ba7c
SM
469 EMACS_INT real_gap_loc;
470 EMACS_INT real_gap_loc_byte;
471 EMACS_INT old_gap_size;
b45433b3
JB
472
473 /* If we have to get more space, get enough to last a while. */
3be11131 474 nbytes_added += 2000;
b45433b3 475
87e32266
SM
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 }
94056516 486
71a7bfa7 487 enlarge_buffer_text (current_buffer, nbytes_added);
b45433b3
JB
488
489 /* Prevent quitting in move_gap. */
490 tem = Vinhibit_quit;
491 Vinhibit_quit = Qt;
492
493 real_gap_loc = GPT;
3be11131 494 real_gap_loc_byte = GPT_BYTE;
b45433b3
JB
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;
7d92db58 499 GPT_BYTE = Z_BYTE + GAP_SIZE;
3be11131 500 GAP_SIZE = nbytes_added;
b45433b3
JB
501
502 /* Move the new gap down to be consecutive with the end of the old one.
503 This adjusts the markers properly too. */
3be11131 504 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1);
b45433b3
JB
505
506 /* Now combine the two into one large gap. */
507 GAP_SIZE += old_gap_size;
508 GPT = real_gap_loc;
3be11131 509 GPT_BYTE = real_gap_loc_byte;
b45433b3 510
469ff680
KH
511 /* Put an anchor. */
512 *(Z_ADDR) = 0;
513
b45433b3
JB
514 Vinhibit_quit = tem;
515}
8af5b8e7
AI
516
517
7273faa1 518/* Make the gap NBYTES_REMOVED bytes shorter. */
8af5b8e7
AI
519
520void
ae19ba7c 521make_gap_smaller (EMACS_INT nbytes_removed)
8af5b8e7
AI
522{
523 Lisp_Object tem;
ae19ba7c
SM
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;
8af5b8e7
AI
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;
73df3b72 541 new_gap_size = GAP_SIZE - nbytes_removed;
8af5b8e7
AI
542 real_Z = Z;
543 real_Z_byte = Z_BYTE;
73df3b72 544 real_beg_unchanged = BEG_UNCHANGED;
8af5b8e7
AI
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. */
72af86bd 549 memset (GPT_ADDR, 0, new_gap_size);
73df3b72
KS
550 GPT += new_gap_size;
551 GPT_BYTE += new_gap_size;
552 Z += new_gap_size;
553 Z_BYTE += new_gap_size;
8af5b8e7
AI
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. */
73df3b72 563 GAP_SIZE = new_gap_size;
8af5b8e7
AI
564 GPT = real_gap_loc;
565 GPT_BYTE = real_gap_loc_byte;
566 Z = real_Z;
567 Z_BYTE = real_Z_byte;
73df3b72 568 BEG_UNCHANGED = real_beg_unchanged;
8af5b8e7
AI
569
570 /* Put an anchor. */
571 *(Z_ADDR) = 0;
572
573 Vinhibit_quit = tem;
574}
575
576void
ae19ba7c 577make_gap (EMACS_INT nbytes_added)
8af5b8e7
AI
578{
579 if (nbytes_added >= 0)
580 make_gap_larger (nbytes_added);
d77fbc16 581#if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
8af5b8e7
AI
582 else
583 make_gap_smaller (-nbytes_added);
584#endif
585}
b45433b3 586\f
2b083808
RS
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
ae19ba7c
SM
594EMACS_INT
595copy_text (const unsigned char *from_addr, unsigned char *to_addr,
596 EMACS_INT nbytes, int from_multibyte, int to_multibyte)
2b083808
RS
597{
598 if (from_multibyte == to_multibyte)
599 {
72af86bd 600 memcpy (to_addr, from_addr, nbytes);
2b083808
RS
601 return nbytes;
602 }
603 else if (from_multibyte)
604 {
ae19ba7c
SM
605 EMACS_INT nchars = 0;
606 EMACS_INT bytes_left = nbytes;
6021f7c5 607 Lisp_Object tbl = Qnil;
f44cbcd8 608
2b083808
RS
609 while (bytes_left > 0)
610 {
b16afa45 611 int thislen, c;
62a6e103 612 c = STRING_CHAR_AND_LENGTH (from_addr, thislen);
1ede3eb6
KH
613 if (! ASCII_CHAR_P (c))
614 c &= 0xFF;
f44cbcd8 615 *to_addr++ = c;
2b083808 616 from_addr += thislen;
7e79b8e0 617 bytes_left -= thislen;
2b083808
RS
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++;
2b083808 630
4c0354d7 631 if (!ASCII_CHAR_P (c))
2b083808 632 {
4c0354d7 633 c = BYTE8_TO_CHAR (c);
0ef71121 634 to_addr += CHAR_STRING (c, to_addr);
2b083808
RS
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
ae19ba7c
SM
649EMACS_INT
650count_size_as_multibyte (const unsigned char *ptr, EMACS_INT nbytes)
2b083808 651{
ae19ba7c
SM
652 EMACS_INT i;
653 EMACS_INT outgoing_nbytes = 0;
2b083808
RS
654
655 for (i = 0; i < nbytes; i++)
656 {
657 unsigned int c = *ptr++;
59a52d50 658
4c0354d7 659 if (ASCII_CHAR_P (c))
59a52d50
KH
660 outgoing_nbytes++;
661 else
2b083808 662 {
4c0354d7 663 c = BYTE8_TO_CHAR (c);
643044eb 664 outgoing_nbytes += CHAR_BYTES (c);
2b083808 665 }
2b083808
RS
666 }
667
668 return outgoing_nbytes;
669}
670\f
b45433b3 671/* Insert a string of specified length before point.
2b083808
RS
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
ef29f213
KH
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. */
b45433b3 678
c660b094 679void
ae19ba7c 680insert (const unsigned char *string, EMACS_INT nbytes)
b45433b3 681{
3be11131 682 if (nbytes > 0)
395ec62e 683 {
ae19ba7c 684 EMACS_INT len = chars_in_text (string, nbytes), opoint;
bab3eee1
EZ
685 insert_1_both (string, len, nbytes, 0, 1, 0);
686 opoint = PT - len;
687 signal_after_change (opoint, 0, len);
0ef71121 688 update_compositions (opoint, PT, CHECK_BORDER);
cd11ef31
RS
689 }
690}
691
2b083808
RS
692/* Likewise, but inherit text properties from neighboring characters. */
693
c660b094 694void
ae19ba7c 695insert_and_inherit (const unsigned char *string, EMACS_INT nbytes)
cd11ef31 696{
3be11131 697 if (nbytes > 0)
cd11ef31 698 {
ae19ba7c 699 EMACS_INT len = chars_in_text (string, nbytes), opoint;
bab3eee1
EZ
700 insert_1_both (string, len, nbytes, 1, 1, 0);
701 opoint = PT - len;
702 signal_after_change (opoint, 0, len);
0ef71121 703 update_compositions (opoint, PT, CHECK_BORDER);
395ec62e
KH
704 }
705}
b45433b3 706
2b083808 707/* Insert the character C before point. Do not inherit text properties. */
3be11131 708
c660b094 709void
ae19ba7c 710insert_char (int c)
3be11131 711{
0ef71121 712 unsigned char str[MAX_MULTIBYTE_LENGTH];
2b083808
RS
713 int len;
714
715 if (! NILP (current_buffer->enable_multibyte_characters))
0ef71121 716 len = CHAR_STRING (c, str);
2b083808
RS
717 else
718 {
719 len = 1;
0ef71121 720 str[0] = c;
2b083808 721 }
3be11131
RS
722
723 insert (str, len);
724}
725
2b083808 726/* Insert the null-terminated string S before point. */
3be11131
RS
727
728void
ae19ba7c 729insert_string (const char *s)
3be11131
RS
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
739void
ae19ba7c 740insert_before_markers (const unsigned char *string, EMACS_INT nbytes)
3be11131
RS
741{
742 if (nbytes > 0)
743 {
ae19ba7c 744 EMACS_INT len = chars_in_text (string, nbytes), opoint;
bab3eee1
EZ
745 insert_1_both (string, len, nbytes, 0, 1, 1);
746 opoint = PT - len;
747 signal_after_change (opoint, 0, len);
0ef71121 748 update_compositions (opoint, PT, CHECK_BORDER);
3be11131
RS
749 }
750}
751
2b083808
RS
752/* Likewise, but inherit text properties from neighboring characters. */
753
3be11131 754void
ae19ba7c
SM
755insert_before_markers_and_inherit (const unsigned char *string,
756 EMACS_INT nbytes)
3be11131
RS
757{
758 if (nbytes > 0)
759 {
ae19ba7c 760 EMACS_INT len = chars_in_text (string, nbytes), opoint;
bab3eee1
EZ
761 insert_1_both (string, len, nbytes, 1, 1, 1);
762 opoint = PT - len;
763 signal_after_change (opoint, 0, len);
0ef71121 764 update_compositions (opoint, PT, CHECK_BORDER);
3be11131
RS
765 }
766}
1f90a790 767
3be11131
RS
768/* Subroutine used by the insert functions above. */
769
770void
ae19ba7c
SM
771insert_1 (const unsigned char *string, EMACS_INT nbytes,
772 int inherit, int prepare, int before_markers)
395ec62e 773{
432f78d2
RS
774 insert_1_both (string, chars_in_text (string, nbytes), nbytes,
775 inherit, prepare, before_markers);
776}
b16afa45 777
1f90a790 778\f
b16afa45
KH
779#ifdef BYTE_COMBINING_DEBUG
780
432f78d2
RS
781/* See if the bytes before POS/POS_BYTE combine with bytes
782 at the start of STRING to form a single character.
ce97a2d7 783 If so, return the number of bytes at the start of STRING
432f78d2 784 which combine in this way. Otherwise, return 0. */
b45433b3 785
432f78d2 786int
ae19ba7c
SM
787count_combining_before (const unsigned char *string, EMACS_INT length,
788 EMACS_INT pos, EMACS_INT pos_byte)
432f78d2 789{
cae184f2 790 int len, combining_bytes;
641a26d2 791 const unsigned char *p;
b45433b3 792
432f78d2
RS
793 if (NILP (current_buffer->enable_multibyte_characters))
794 return 0;
cae184f2
KH
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) */
432f78d2 801 return 0;
cae184f2 802 if (pos_byte == BEG_BYTE) /* case (2) */
432f78d2 803 return 0;
cae184f2
KH
804 len = 1;
805 p = BYTE_POS_ADDR (pos_byte - 1);
806 while (! CHAR_HEAD_P (*p)) p--, len++;
409f2919 807 if (! LEADING_CODE_P (*p)) /* case (3) */
432f78d2 808 return 0;
cae184f2 809
cae184f2
KH
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). */
432f78d2 815 return 0;
ce97a2d7 816
cae184f2
KH
817 /* We have a combination situation. Count the bytes at STRING that
818 may combine. */
819 p = string + 1;
ce97a2d7
RS
820 while (!CHAR_HEAD_P (*p) && p < string + length)
821 p++;
822
cae184f2 823 return (combining_bytes < p - string ? combining_bytes : p - string);
432f78d2 824}
b45433b3 825
432f78d2
RS
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. */
679194a6 830
432f78d2 831int
ae19ba7c
SM
832count_combining_after (const unsigned char *string,
833 EMACS_INT length, EMACS_INT pos, EMACS_INT pos_byte)
432f78d2 834{
ae19ba7c
SM
835 EMACS_INT opos_byte = pos_byte;
836 EMACS_INT i;
837 EMACS_INT bytes;
cae184f2 838 unsigned char *bufp;
3be11131 839
432f78d2
RS
840 if (NILP (current_buffer->enable_multibyte_characters))
841 return 0;
cae184f2
KH
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) */
432f78d2 851 return 0;
cae184f2
KH
852 bufp = BYTE_POS_ADDR (pos_byte);
853 if (CHAR_HEAD_P (*bufp)) /* case (3) */
854 return 0;
855
432f78d2 856 i = length - 1;
b57a7b0b 857 while (i >= 0 && ! CHAR_HEAD_P (string[i]))
432f78d2
RS
858 {
859 i--;
860 }
b57a7b0b
KH
861 if (i < 0)
862 {
cae184f2
KH
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;
b57a7b0b 867 i = pos_byte - 2;
cae184f2 868 while (i >= 0 && ! CHAR_HEAD_P (p[i]))
b57a7b0b 869 i--;
409f2919 870 if (i < 0 || !LEADING_CODE_P (p[i]))
b57a7b0b 871 return 0;
0ef71121 872
cae184f2
KH
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));
b57a7b0b 877 }
409f2919 878 if (!LEADING_CODE_P (string[i]))
432f78d2
RS
879 return 0;
880
cae184f2
KH
881 bytes = BYTES_BY_CHAR_HEAD (string[i]) - (length - i);
882 bufp++, pos_byte++;
883 while (!CHAR_HEAD_P (*bufp)) bufp++, pos_byte++;
cd11ef31 884
cae184f2 885 return (bytes <= pos_byte - opos_byte ? bytes : pos_byte - opos_byte);
b45433b3 886}
2b083808 887
b16afa45 888#endif
9f3ede3c 889
1f90a790 890\f
2b083808
RS
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
895void
ae19ba7c
SM
896insert_1_both (const unsigned char *string,
897 EMACS_INT nchars, EMACS_INT nbytes,
898 int inherit, int prepare, int before_markers)
2b083808 899{
da80a8d5
GM
900 if (nchars == 0)
901 return;
177c0ea7 902
57404188
KH
903 if (NILP (current_buffer->enable_multibyte_characters))
904 nchars = nbytes;
905
35d63725
RS
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
2b083808
RS
912 if (PT != GPT)
913 move_gap_both (PT, PT_BYTE);
914 if (GAP_SIZE < nbytes)
915 make_gap (nbytes - GAP_SIZE);
916
b16afa45
KH
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
432f78d2
RS
922
923 /* Record deletion of the surrounding text that combines with
924 the insertion. This, together with recording the insertion,
b16afa45
KH
925 will add up to the right stuff in the undo list. */
926 record_insert (PT, nchars);
2b083808 927 MODIFF++;
3e145152 928 CHARS_MODIFF = MODIFF;
2b083808 929
72af86bd 930 memcpy (GPT_ADDR, string, nbytes);
2b083808 931
2b083808 932 GAP_SIZE -= nbytes;
1f90a790
RS
933 GPT += nchars;
934 ZV += nchars;
935 Z += nchars;
2b083808
RS
936 GPT_BYTE += nbytes;
937 ZV_BYTE += nbytes;
938 Z_BYTE += nbytes;
939 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1f90a790 940
1f90a790
RS
941 if (GPT_BYTE < GPT)
942 abort ();
943
9dde4e0c
KS
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
1f90a790 948 adjust_overlays_for_insert (PT, nchars);
432f78d2 949 adjust_markers_for_insert (PT, PT_BYTE,
1f90a790 950 PT + nchars, PT_BYTE + nbytes,
2b083808 951 before_markers);
ce97a2d7 952
1f90a790 953 if (BUF_INTERVALS (current_buffer) != 0)
1f90a790
RS
954 offset_intervals (current_buffer, PT, nchars);
955
ce97a2d7 956 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
f2cab2ea
GM
957 set_text_properties (make_number (PT), make_number (PT + nchars),
958 Qnil, Qnil, Qnil);
ce97a2d7 959
b16afa45 960 adjust_point (nchars, nbytes);
828f1ed3
KH
961
962 CHECK_MARKERS ();
2b083808 963}
3be11131 964\f
679194a6 965/* Insert the part of the text of STRING, a Lisp object assumed to be
2b083808
RS
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.
679194a6
JA
969
970 It does not work to use `insert' for this, because a GC could happen
72af86bd 971 before we copy the stuff into the buffer, and relocate the string
7e1ea612 972 without insert noticing. */
679194a6 973
c660b094 974void
ae19ba7c
SM
975insert_from_string (Lisp_Object string, EMACS_INT pos, EMACS_INT pos_byte,
976 EMACS_INT length, EMACS_INT length_byte, int inherit)
395ec62e 977{
ae19ba7c 978 EMACS_INT opoint = PT;
d8bf4256
RS
979
980 if (SCHARS (string) == 0)
981 return;
982
62b82678
RS
983 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
984 inherit, 0);
985 signal_after_change (opoint, 0, PT - opoint);
0ef71121 986 update_compositions (opoint, PT, CHECK_BORDER);
395ec62e
KH
987}
988
2b083808
RS
989/* Like `insert_from_string' except that all markers pointing
990 at the place where the insertion happens are adjusted to point after it. */
3be11131
RS
991
992void
ae19ba7c
SM
993insert_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)
3be11131 997{
ae19ba7c 998 EMACS_INT opoint = PT;
d8bf4256
RS
999
1000 if (SCHARS (string) == 0)
1001 return;
1002
62b82678
RS
1003 insert_from_string_1 (string, pos, pos_byte, length, length_byte,
1004 inherit, 1);
1005 signal_after_change (opoint, 0, PT - opoint);
0ef71121 1006 update_compositions (opoint, PT, CHECK_BORDER);
3be11131
RS
1007}
1008
1009/* Subroutine of the insertion functions above. */
1010
1011static void
ae19ba7c
SM
1012insert_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)
b45433b3 1015{
b45433b3 1016 struct gcpro gcpro1;
ae19ba7c 1017 EMACS_INT outgoing_nbytes = nbytes;
ce97a2d7 1018 INTERVAL intervals;
2b083808
RS
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;
2a1d8be0 1025 else if (! STRING_MULTIBYTE (string))
2b083808 1026 outgoing_nbytes
f7e233a8 1027 = count_size_as_multibyte (SDATA (string) + pos_byte,
2b083808 1028 nbytes);
b45433b3 1029
b45433b3 1030 GCPRO1 (string);
35d63725
RS
1031 /* Do this before moving and increasing the gap,
1032 because the before-change hooks might move the gap
1033 or make it smaller. */
d206af14 1034 prepare_to_modify_buffer (PT, PT, NULL);
b45433b3 1035
2bcaed71 1036 if (PT != GPT)
3be11131 1037 move_gap_both (PT, PT_BYTE);
534b9840 1038 if (GAP_SIZE < outgoing_nbytes)
2b083808 1039 make_gap (outgoing_nbytes - GAP_SIZE);
b45433b3
JB
1040 UNGCPRO;
1041
2b083808
RS
1042 /* Copy the string text into the buffer, perhaps converting
1043 between single-byte and multibyte. */
d5db4077 1044 copy_text (SDATA (string) + pos_byte, GPT_ADDR, nbytes,
2a1d8be0 1045 STRING_MULTIBYTE (string),
2b083808 1046 ! NILP (current_buffer->enable_multibyte_characters));
b45433b3 1047
b16afa45 1048#ifdef BYTE_COMBINING_DEBUG
432f78d2
RS
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. */
b16afa45
KH
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
432f78d2 1058
b16afa45 1059 record_insert (PT, nchars);
432f78d2 1060 MODIFF++;
3e145152 1061 CHARS_MODIFF = MODIFF;
432f78d2 1062
7792090e 1063 GAP_SIZE -= outgoing_nbytes;
1f90a790
RS
1064 GPT += nchars;
1065 ZV += nchars;
1066 Z += nchars;
2b083808
RS
1067 GPT_BYTE += outgoing_nbytes;
1068 ZV_BYTE += outgoing_nbytes;
1069 Z_BYTE += outgoing_nbytes;
469ff680 1070 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
3be11131
RS
1071
1072 if (GPT_BYTE < GPT)
1073 abort ();
679194a6 1074
9dde4e0c
KS
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
1f90a790
RS
1079 adjust_overlays_for_insert (PT, nchars);
1080 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1081 PT_BYTE + outgoing_nbytes,
1f90a790 1082 before_markers);
ce97a2d7 1083
1f90a790
RS
1084 offset_intervals (current_buffer, PT, nchars);
1085
d5db4077 1086 intervals = STRING_INTERVALS (string);
b16afa45 1087 /* Get the intervals for the part of the string we are inserting. */
d5db4077 1088 if (nbytes < SBYTES (string))
1f90a790 1089 intervals = copy_intervals (intervals, pos, nchars);
177c0ea7 1090
ce97a2d7 1091 /* Insert those intervals. */
1f90a790 1092 graft_intervals_into_buffer (intervals, PT, nchars,
9391e591 1093 current_buffer, inherit);
ce97a2d7 1094
b16afa45 1095 adjust_point (nchars, outgoing_nbytes);
8f924df7
KH
1096
1097 CHECK_MARKERS ();
1098}
1099\f
1100/* Insert a sequence of NCHARS chars which occupy NBYTES bytes
1101 starting at GPT_ADDR. */
1102
1103void
ae19ba7c 1104insert_from_gap (EMACS_INT nchars, EMACS_INT nbytes)
8f924df7
KH
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
c669988b
KH
1124 adjust_overlays_for_insert (GPT - nchars, nchars);
1125 adjust_markers_for_insert (GPT - nchars, GPT_BYTE - nbytes,
1126 GPT, GPT_BYTE, 0);
8f924df7
KH
1127
1128 if (BUF_INTERVALS (current_buffer) != 0)
c669988b
KH
1129 {
1130 offset_intervals (current_buffer, GPT - nchars, nchars);
1131 graft_intervals_into_buffer (NULL_INTERVAL, GPT - nchars, nchars,
1132 current_buffer, 0);
1133 }
8f924df7
KH
1134
1135 if (GPT - nchars < PT)
1136 adjust_point (nchars, nbytes);
1137
1138 CHECK_MARKERS ();
b45433b3 1139}
3be11131
RS
1140\f
1141/* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
ef29f213
KH
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
72af86bd 1146 and relocate BUF's text before the copy happens. */
ef29f213
KH
1147
1148void
ae19ba7c
SM
1149insert_from_buffer (struct buffer *buf,
1150 EMACS_INT charpos, EMACS_INT nchars, int inherit)
ef29f213 1151{
ae19ba7c 1152 EMACS_INT opoint = PT;
3be11131 1153
62b82678
RS
1154 insert_from_buffer_1 (buf, charpos, nchars, inherit);
1155 signal_after_change (opoint, 0, PT - opoint);
0ef71121 1156 update_compositions (opoint, PT, CHECK_BORDER);
ef29f213
KH
1157}
1158
1159static void
ae19ba7c
SM
1160insert_from_buffer_1 (struct buffer *buf,
1161 EMACS_INT from, EMACS_INT nchars, int inherit)
ef29f213 1162{
0aa8c4b2 1163 register Lisp_Object temp;
ae19ba7c
SM
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;
ce97a2d7 1169 INTERVAL intervals;
2b083808
RS
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))
4468c4f1 1177 {
ae19ba7c
SM
1178 EMACS_INT outgoing_before_gap = 0;
1179 EMACS_INT outgoing_after_gap = 0;
ef29f213 1180
4468c4f1
KH
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
177c0ea7 1195 = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf,
4468c4f1
KH
1196 from_byte + chunk),
1197 incoming_nbytes - chunk);
1198
1199 outgoing_nbytes = outgoing_before_gap + outgoing_after_gap;
1200 }
177c0ea7 1201
ef29f213 1202 /* Make sure point-max won't overflow after this insertion. */
2b083808
RS
1203 XSETINT (temp, outgoing_nbytes + Z);
1204 if (outgoing_nbytes + Z != XINT (temp))
3be11131 1205 error ("Maximum buffer size exceeded");
ef29f213 1206
35d63725
RS
1207 /* Do this before moving and increasing the gap,
1208 because the before-change hooks might move the gap
1209 or make it smaller. */
d206af14 1210 prepare_to_modify_buffer (PT, PT, NULL);
ef29f213
KH
1211
1212 if (PT != GPT)
3be11131 1213 move_gap_both (PT, PT_BYTE);
2b083808
RS
1214 if (GAP_SIZE < outgoing_nbytes)
1215 make_gap (outgoing_nbytes - GAP_SIZE);
ef29f213 1216
3be11131 1217 if (from < BUF_GPT (buf))
ef29f213 1218 {
3be11131 1219 chunk = BUF_GPT_BYTE (buf) - from_byte;
2b083808
RS
1220 if (chunk > incoming_nbytes)
1221 chunk = incoming_nbytes;
4468c4f1
KH
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));
ef29f213
KH
1229 }
1230 else
4468c4f1
KH
1231 chunk_expanded = chunk = 0;
1232
2b083808
RS
1233 if (chunk < incoming_nbytes)
1234 copy_text (BUF_BYTE_ADDRESS (buf, from_byte + chunk),
4468c4f1 1235 GPT_ADDR + chunk_expanded, incoming_nbytes - chunk,
2b083808
RS
1236 ! NILP (buf->enable_multibyte_characters),
1237 ! NILP (current_buffer->enable_multibyte_characters));
ef29f213 1238
b16afa45 1239#ifdef BYTE_COMBINING_DEBUG
432f78d2
RS
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
1f90a790 1243 have got earlier on. Meanwhile, GPT_ADDR does point to
432f78d2 1244 the text that has been stored by copy_text. */
b16afa45
KH
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
432f78d2 1249
b16afa45 1250 record_insert (PT, nchars);
432f78d2 1251 MODIFF++;
3e145152 1252 CHARS_MODIFF = MODIFF;
432f78d2 1253
2b083808 1254 GAP_SIZE -= outgoing_nbytes;
1f90a790
RS
1255 GPT += nchars;
1256 ZV += nchars;
1257 Z += nchars;
2b083808
RS
1258 GPT_BYTE += outgoing_nbytes;
1259 ZV_BYTE += outgoing_nbytes;
1260 Z_BYTE += outgoing_nbytes;
469ff680 1261 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1f90a790 1262
1f90a790
RS
1263 if (GPT_BYTE < GPT)
1264 abort ();
1265
9dde4e0c
KS
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
1f90a790
RS
1270 adjust_overlays_for_insert (PT, nchars);
1271 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
432f78d2 1272 PT_BYTE + outgoing_nbytes,
b16afa45 1273 0);
ce97a2d7 1274
1f90a790
RS
1275 if (BUF_INTERVALS (current_buffer) != 0)
1276 offset_intervals (current_buffer, PT, nchars);
ce97a2d7 1277
b16afa45 1278 /* Get the intervals for the part of the string we are inserting. */
ce97a2d7 1279 intervals = BUF_INTERVALS (buf);
f1a6b216 1280 if (nchars < BUF_Z (buf) - BUF_BEG (buf))
06d8227a
GM
1281 {
1282 if (buf == current_buffer && PT <= from)
1283 from += nchars;
1284 intervals = copy_intervals (intervals, from, nchars);
1285 }
177c0ea7 1286
ce97a2d7 1287 /* Insert those intervals. */
1f90a790 1288 graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
ce97a2d7 1289
b16afa45 1290 adjust_point (nchars, outgoing_nbytes);
b45433b3
JB
1291}
1292\f
652838b5
KH
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. */
2d9eea44 1299
1e9c7b7d 1300void
ae19ba7c
SM
1301adjust_after_replace (EMACS_INT from, EMACS_INT from_byte,
1302 Lisp_Object prev_text, EMACS_INT len, EMACS_INT len_byte)
1e9c7b7d 1303{
ae19ba7c 1304 EMACS_INT nchars_del = 0, nbytes_del = 0;
61415a25 1305
b16afa45
KH
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
828f1ed3
KH
1312 if (STRINGP (prev_text))
1313 {
d5db4077
KR
1314 nchars_del = SCHARS (prev_text);
1315 nbytes_del = SBYTES (prev_text);
828f1ed3
KH
1316 }
1317
61415a25
KH
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
adee4f91
KH
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);
b16afa45 1331
828f1ed3
KH
1332 if (! EQ (current_buffer->undo_list, Qt))
1333 {
828f1ed3 1334 if (nchars_del > 0)
b16afa45
KH
1335 record_delete (from, prev_text);
1336 record_insert (from, len);
828f1ed3 1337 }
652838b5
KH
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);
61415a25 1343 if (BUF_INTERVALS (current_buffer) != 0)
4a7cf15f
KH
1344 {
1345 offset_intervals (current_buffer, from, len - nchars_del);
4a7cf15f 1346 }
61415a25 1347
b16afa45
KH
1348 if (from < PT)
1349 adjust_point (len - nchars_del, len_byte - nbytes_del);
61415a25 1350
9f3ede3c 1351 /* As byte combining will decrease Z, we must check this again. */
a50df55b
GM
1352 if (Z - GPT < END_UNCHANGED)
1353 END_UNCHANGED = Z - GPT;
9f3ede3c 1354
60ea6052
RS
1355 CHECK_MARKERS ();
1356
1e9c7b7d 1357 if (len == 0)
b58e3ca1
RS
1358 evaporate_overlays (from);
1359 MODIFF++;
3e145152 1360 CHARS_MODIFF = MODIFF;
b58e3ca1
RS
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
1366void
ae19ba7c
SM
1367adjust_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)
b58e3ca1
RS
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)
1e9c7b7d
KH
1410 evaporate_overlays (from);
1411 MODIFF++;
3e145152 1412 CHARS_MODIFF = MODIFF;
1e9c7b7d
KH
1413}
1414
652838b5
KH
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
1420void
ae19ba7c
SM
1421adjust_after_insert (EMACS_INT from, EMACS_INT from_byte,
1422 EMACS_INT to, EMACS_INT to_byte, EMACS_INT newlen)
652838b5 1423{
ae19ba7c 1424 EMACS_INT len = to - from, len_byte = to_byte - from_byte;
652838b5
KH
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}
085db7de 1434\f
3be11131 1435/* Replace the text from character positions FROM to TO with NEW,
c5ca4d3a
RS
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.
60aa777a
RS
1443 That way, undo will also handle markers properly.
1444
1445 But if MARKERS is 0, don't relocate markers. */
c5ca4d3a
RS
1446
1447void
ae19ba7c
SM
1448replace_range (EMACS_INT from, EMACS_INT to, Lisp_Object new,
1449 int prepare, int inherit, int markers)
c5ca4d3a 1450{
ae19ba7c
SM
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;
c5ca4d3a
RS
1455 register Lisp_Object temp;
1456 struct gcpro gcpro1;
ce97a2d7 1457 INTERVAL intervals;
ae19ba7c 1458 EMACS_INT outgoing_insbytes = insbytes;
23b20a70 1459 Lisp_Object deletion;
c5ca4d3a 1460
60ea6052
RS
1461 CHECK_MARKERS ();
1462
c5ca4d3a 1463 GCPRO1 (new);
6bbd7a29 1464 deletion = Qnil;
c5ca4d3a
RS
1465
1466 if (prepare)
1467 {
ae19ba7c 1468 EMACS_INT range_length = to - from;
c5ca4d3a
RS
1469 prepare_to_modify_buffer (from, to, &from);
1470 to = from + range_length;
1471 }
1472
3be11131
RS
1473 UNGCPRO;
1474
c5ca4d3a
RS
1475 /* Make args be valid */
1476 if (from < BEGV)
1477 from = BEGV;
1478 if (to > ZV)
1479 to = ZV;
1480
3be11131
RS
1481 from_byte = CHAR_TO_BYTE (from);
1482 to_byte = CHAR_TO_BYTE (to);
c5ca4d3a 1483
3be11131
RS
1484 nchars_del = to - from;
1485 nbytes_del = to_byte - from_byte;
1486
1487 if (nbytes_del <= 0 && insbytes == 0)
1488 return;
c5ca4d3a 1489
1f90a790
RS
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;
2a1d8be0 1495 else if (! STRING_MULTIBYTE (new))
1f90a790 1496 outgoing_insbytes
d5db4077 1497 = count_size_as_multibyte (SDATA (new), insbytes);
1f90a790 1498
c5ca4d3a 1499 /* Make sure point-max won't overflow after this insertion. */
3be11131
RS
1500 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1501 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
1502 error ("Maximum buffer size exceeded");
c5ca4d3a 1503
c5ca4d3a
RS
1504 GCPRO1 (new);
1505
1506 /* Make sure the gap is somewhere in or next to what we are deleting. */
1507 if (from > GPT)
3be11131 1508 gap_right (from, from_byte);
c5ca4d3a 1509 if (to < GPT)
3be11131 1510 gap_left (to, to_byte, 0);
c5ca4d3a 1511
039af53a
KH
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. */
b16afa45
KH
1515 if (! EQ (current_buffer->undo_list, Qt))
1516 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
c5ca4d3a 1517
3be11131
RS
1518 GAP_SIZE += nbytes_del;
1519 ZV -= nchars_del;
1520 Z -= nchars_del;
1521 ZV_BYTE -= nbytes_del;
1522 Z_BYTE -= nbytes_del;
c5ca4d3a 1523 GPT = from;
3be11131 1524 GPT_BYTE = from_byte;
017e09ac 1525 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
c5ca4d3a 1526
3be11131
RS
1527 if (GPT_BYTE < GPT)
1528 abort ();
1529
a50df55b
GM
1530 if (GPT - BEG < BEG_UNCHANGED)
1531 BEG_UNCHANGED = GPT - BEG;
1532 if (Z - GPT < END_UNCHANGED)
1533 END_UNCHANGED = Z - GPT;
c5ca4d3a 1534
3be11131
RS
1535 if (GAP_SIZE < insbytes)
1536 make_gap (insbytes - GAP_SIZE);
c5ca4d3a 1537
1f90a790
RS
1538 /* Copy the string text into the buffer, perhaps converting
1539 between single-byte and multibyte. */
d5db4077 1540 copy_text (SDATA (new), GPT_ADDR, insbytes,
2a1d8be0 1541 STRING_MULTIBYTE (new),
1f90a790
RS
1542 ! NILP (current_buffer->enable_multibyte_characters));
1543
b16afa45 1544#ifdef BYTE_COMBINING_DEBUG
255c7dae
RS
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
432f78d2 1549 the text that has been stored by copy_text. */
b16afa45
KH
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
432f78d2 1554
23b20a70
KH
1555 if (! EQ (current_buffer->undo_list, Qt))
1556 {
bec1aca2
RS
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);
b16afa45 1562 record_delete (from, deletion);
23b20a70 1563 }
c5ca4d3a 1564
1f90a790
RS
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;
c5ca4d3a
RS
1572 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1573
3be11131
RS
1574 if (GPT_BYTE < GPT)
1575 abort ();
1576
c5ca4d3a
RS
1577 /* Adjust the overlay center as needed. This must be done after
1578 adjusting the markers that bound the overlays. */
3be11131 1579 adjust_overlays_for_delete (from, nchars_del);
1f90a790 1580 adjust_overlays_for_insert (from, inschars);
048a0fbb
RS
1581
1582 /* Adjust markers for the deletion and the insertion. */
60aa777a 1583 if (markers)
048a0fbb
RS
1584 adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
1585 inschars, outgoing_insbytes);
c5ca4d3a 1586
255c7dae 1587 offset_intervals (current_buffer, from, inschars - nchars_del);
ce97a2d7
RS
1588
1589 /* Get the intervals for the part of the string we are inserting--
1590 not including the combined-before bytes. */
d5db4077 1591 intervals = STRING_INTERVALS (new);
ce97a2d7 1592 /* Insert those intervals. */
1f90a790 1593 graft_intervals_into_buffer (intervals, from, inschars,
ce97a2d7 1594 current_buffer, inherit);
c5ca4d3a 1595
1f90a790
RS
1596 /* Relocate point as if it were a marker. */
1597 if (from < PT)
8bedbe9d 1598 adjust_point ((from + inschars - (PT < to ? PT : to)),
1f90a790 1599 (from_byte + outgoing_insbytes
8bedbe9d 1600 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
c5ca4d3a 1601
1f90a790
RS
1602 if (outgoing_insbytes == 0)
1603 evaporate_overlays (from);
93b882e8 1604
60ea6052
RS
1605 CHECK_MARKERS ();
1606
c5ca4d3a 1607 MODIFF++;
3e145152 1608 CHARS_MODIFF = MODIFF;
c5ca4d3a
RS
1609 UNGCPRO;
1610
255c7dae 1611 signal_after_change (from, nchars_del, GPT - from);
0ef71121 1612 update_compositions (from, GPT, CHECK_BORDER);
c5ca4d3a
RS
1613}
1614\f
085db7de
RS
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
1627void
ae19ba7c
SM
1628replace_range_2 (EMACS_INT from, EMACS_INT from_byte,
1629 EMACS_INT to, EMACS_INT to_byte,
a8fe7202 1630 const char *ins, EMACS_INT inschars, EMACS_INT insbytes,
ae19ba7c 1631 int markers)
085db7de 1632{
ae19ba7c 1633 EMACS_INT nbytes_del, nchars_del;
085db7de
RS
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. */
72af86bd 1676 memcpy (GPT_ADDR, ins, insbytes);
085db7de
RS
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
7077904e 1711 && ! (nchars_del == 1 && inschars == 1 && nbytes_del == insbytes))
085db7de
RS
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. */
7077904e
KH
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 }
085db7de
RS
1726
1727 if (insbytes == 0)
1728 evaporate_overlays (from);
1729
1730 CHECK_MARKERS ();
1731
1732 MODIFF++;
3e145152 1733 CHARS_MODIFF = MODIFF;
085db7de
RS
1734}
1735\f
b45433b3 1736/* Delete characters in current buffer
3be11131
RS
1737 from FROM up to (but not including) TO.
1738 If TO comes before FROM, we delete nothing. */
b45433b3 1739
c660b094 1740void
ae19ba7c 1741del_range (EMACS_INT from, EMACS_INT to)
47c64747 1742{
7dae4502 1743 del_range_1 (from, to, 1, 0);
47c64747
RS
1744}
1745
7dae4502
SM
1746/* Like del_range; PREPARE says whether to call prepare_to_modify_buffer.
1747 RET_STRING says to return the deleted text. */
47c64747 1748
7dae4502 1749Lisp_Object
ae19ba7c 1750del_range_1 (EMACS_INT from, EMACS_INT to, int prepare, int ret_string)
b45433b3 1751{
ae19ba7c 1752 EMACS_INT from_byte, to_byte;
7dae4502
SM
1753 Lisp_Object deletion;
1754 struct gcpro gcpro1;
3be11131
RS
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)
7dae4502 1763 return Qnil;
3be11131
RS
1764
1765 if (prepare)
1766 {
ae19ba7c 1767 EMACS_INT range_length = to - from;
3be11131 1768 prepare_to_modify_buffer (from, to, &from);
0a411995 1769 to = min (ZV, from + range_length);
3be11131
RS
1770 }
1771
1772 from_byte = CHAR_TO_BYTE (from);
1773 to_byte = CHAR_TO_BYTE (to);
1774
7dae4502
SM
1775 deletion = del_range_2 (from, from_byte, to, to_byte, ret_string);
1776 GCPRO1(deletion);
9c36993a 1777 signal_after_change (from, to - from, 0);
233cc02d 1778 update_compositions (from, from, CHECK_HEAD);
7dae4502
SM
1779 UNGCPRO;
1780 return deletion;
3be11131
RS
1781}
1782
1783/* Like del_range_1 but args are byte positions, not char positions. */
1784
1785void
ae19ba7c 1786del_range_byte (EMACS_INT from_byte, EMACS_INT to_byte, int prepare)
3be11131 1787{
ae19ba7c 1788 EMACS_INT from, to;
3be11131
RS
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);
b45433b3 1801
d206af14
RS
1802 if (prepare)
1803 {
ae19ba7c
SM
1804 EMACS_INT old_from = from, old_to = Z - to;
1805 EMACS_INT range_length = to - from;
d206af14
RS
1806 prepare_to_modify_buffer (from, to, &from);
1807 to = from + range_length;
3be11131
RS
1808
1809 if (old_from != from)
1810 from_byte = CHAR_TO_BYTE (from);
0a411995
GM
1811 if (to > ZV)
1812 {
1813 to = ZV;
1814 to_byte = ZV_BYTE;
1815 }
1816 else if (old_to == Z - to)
3be11131 1817 to_byte = CHAR_TO_BYTE (to);
d206af14
RS
1818 }
1819
7dae4502 1820 del_range_2 (from, from_byte, to, to_byte, 0);
9c36993a 1821 signal_after_change (from, to - from, 0);
0ef71121 1822 update_compositions (from, from, CHECK_HEAD);
3be11131
RS
1823}
1824
1825/* Like del_range_1, but positions are specified both as charpos
1826 and bytepos. */
1827
1828void
ae19ba7c
SM
1829del_range_both (EMACS_INT from, EMACS_INT from_byte,
1830 EMACS_INT to, EMACS_INT to_byte, int prepare)
3be11131 1831{
b45433b3 1832 /* Make args be valid */
3be11131
RS
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
b45433b3
JB
1841 if (from < BEGV)
1842 from = BEGV;
1843 if (to > ZV)
1844 to = ZV;
1845
3be11131
RS
1846 if (prepare)
1847 {
ae19ba7c
SM
1848 EMACS_INT old_from = from, old_to = Z - to;
1849 EMACS_INT range_length = to - from;
3be11131
RS
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);
0a411995
GM
1855 if (to > ZV)
1856 {
1857 to = ZV;
1858 to_byte = ZV_BYTE;
1859 }
1860 else if (old_to == Z - to)
3be11131
RS
1861 to_byte = CHAR_TO_BYTE (to);
1862 }
1863
7dae4502 1864 del_range_2 (from, from_byte, to, to_byte, 0);
9c36993a 1865 signal_after_change (from, to - from, 0);
0ef71121 1866 update_compositions (from, from, CHECK_HEAD);
3be11131
RS
1867}
1868
1869/* Delete a range of text, specified both as character positions
1870 and byte positions. FROM and TO are character positions,
7dae4502
SM
1871 while FROM_BYTE and TO_BYTE are byte positions.
1872 If RET_STRING is true, the deleted area is returned as a string. */
3be11131 1873
7dae4502 1874Lisp_Object
ae19ba7c
SM
1875del_range_2 (EMACS_INT from, EMACS_INT from_byte,
1876 EMACS_INT to, EMACS_INT to_byte, int ret_string)
3be11131 1877{
ae19ba7c 1878 register EMACS_INT nbytes_del, nchars_del;
628cea90 1879 Lisp_Object deletion;
3be11131 1880
60ea6052
RS
1881 CHECK_MARKERS ();
1882
3be11131
RS
1883 nchars_del = to - from;
1884 nbytes_del = to_byte - from_byte;
b45433b3
JB
1885
1886 /* Make sure the gap is somewhere in or next to what we are deleting. */
1887 if (from > GPT)
3be11131 1888 gap_right (from, from_byte);
b45433b3 1889 if (to < GPT)
3be11131 1890 gap_left (to, to_byte, 0);
b45433b3 1891
b16afa45
KH
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
628cea90 1897
7dae4502 1898 if (ret_string || ! EQ (current_buffer->undo_list, Qt))
b16afa45 1899 deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
7dae4502
SM
1900 else
1901 deletion = Qnil;
1902
8948d317
RS
1903 /* Relocate all markers pointing into the new, larger gap
1904 to point at the end of the text before the gap.
3be11131
RS
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);
b16afa45 1908
0aa8c4b2 1909 if (! EQ (current_buffer->undo_list, Qt))
b16afa45 1910 record_delete (from, deletion);
be09561e 1911 MODIFF++;
3e145152 1912 CHARS_MODIFF = MODIFF;
be09561e 1913
b45433b3 1914 /* Relocate point as if it were a marker. */
2bcaed71 1915 if (from < PT)
3be11131
RS
1916 adjust_point (from - (PT < to ? PT : to),
1917 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte));
b45433b3 1918
3be11131 1919 offset_intervals (current_buffer, from, - nchars_del);
16032db6 1920
adde4858 1921 /* Adjust the overlay center as needed. This must be done after
a7f38d28 1922 adjusting the markers that bound the overlays. */
e3a87305 1923 adjust_overlays_for_delete (from, nchars_del);
adde4858 1924
3be11131
RS
1925 GAP_SIZE += nbytes_del;
1926 ZV_BYTE -= nbytes_del;
1927 Z_BYTE -= nbytes_del;
1928 ZV -= nchars_del;
1929 Z -= nchars_del;
b45433b3 1930 GPT = from;
3be11131 1931 GPT_BYTE = from_byte;
b3b58c01
AS
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;
e3a87305 1936
3be11131
RS
1937 if (GPT_BYTE < GPT)
1938 abort ();
1939
a50df55b
GM
1940 if (GPT - BEG < BEG_UNCHANGED)
1941 BEG_UNCHANGED = GPT - BEG;
1942 if (Z - GPT < END_UNCHANGED)
1943 END_UNCHANGED = Z - GPT;
b45433b3 1944
60ea6052
RS
1945 CHECK_MARKERS ();
1946
d386034e 1947 evaporate_overlays (from);
7dae4502
SM
1948
1949 return deletion;
b45433b3
JB
1950}
1951\f
3be11131
RS
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
3e145152
CY
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. */
3be11131 1960
c660b094 1961void
ae19ba7c
SM
1962modify_region (struct buffer *buffer, EMACS_INT start, EMACS_INT end,
1963 int preserve_chars_modiff)
b45433b3 1964{
04a759c8
JB
1965 struct buffer *old_buffer = current_buffer;
1966
1967 if (buffer != old_buffer)
1968 set_buffer_internal (buffer);
1969
d206af14 1970 prepare_to_modify_buffer (start, end, NULL);
b45433b3 1971
a50df55b 1972 BUF_COMPUTE_UNCHANGED (buffer, start - 1, end);
83010cd6 1973
9fbf87cd 1974 if (MODIFF <= SAVE_MODIFF)
83010cd6 1975 record_first_change ();
b45433b3 1976 MODIFF++;
3e145152
CY
1977 if (! preserve_chars_modiff)
1978 CHARS_MODIFF = MODIFF;
04a759c8 1979
069cdc4f
RS
1980 buffer->point_before_scroll = Qnil;
1981
04a759c8
JB
1982 if (buffer != old_buffer)
1983 set_buffer_internal (old_buffer);
b45433b3 1984}
d206af14 1985\f
3be11131
RS
1986/* Check that it is okay to modify the buffer between START and END,
1987 which are char positions.
1988
679194a6
JA
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
d206af14
RS
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. */
b45433b3 1995
c660b094 1996void
9628fed7
SM
1997prepare_to_modify_buffer (EMACS_INT start, EMACS_INT end,
1998 EMACS_INT *preserve_ptr)
b45433b3 1999{
234fb773
CY
2000 struct buffer *base_buffer;
2001
d427b66a 2002 if (!NILP (current_buffer->read_only))
b45433b3
JB
2003 Fbarf_if_buffer_read_only ();
2004
2e9f55fd
GM
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
9fbf87cd 2010 if (BUF_INTERVALS (current_buffer) != 0)
d206af14
RS
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);
dab0b04d 2020 unchain_marker (XMARKER (preserve_marker));
d206af14
RS
2021 UNGCPRO;
2022 }
2023 else
2024 verify_interval_modification (current_buffer, start, end);
2025 }
b45433b3 2026
234fb773
CY
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
b45433b3 2033#ifdef CLASH_DETECTION
234fb773 2034 if (!NILP (base_buffer->file_truename)
ab6c5c0c 2035 /* Make binding buffer-file-name to nil effective. */
234fb773 2036 && !NILP (base_buffer->filename)
9fbf87cd 2037 && SAVE_MODIFF >= MODIFF)
234fb773 2038 lock_file (base_buffer->file_truename);
b45433b3
JB
2039#else
2040 /* At least warn if this file has changed on disk since it was visited. */
234fb773 2041 if (!NILP (base_buffer->filename)
9fbf87cd 2042 && SAVE_MODIFF >= MODIFF
d427b66a 2043 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
234fb773 2044 && !NILP (Ffile_exists_p (base_buffer->filename)))
b45433b3 2045 call1 (intern ("ask-user-about-supersession-threat"),
234fb773 2046 base_buffer->filename);
b45433b3
JB
2047#endif /* not CLASH_DETECTION */
2048
9852377f 2049 /* If `select-active-regions' is non-nil, save the region text. */
7c23dd44 2050 if (!NILP (current_buffer->mark_active)
8b78d5e3 2051 && !inhibit_modification_hooks
d24ec09a 2052 && XMARKER (current_buffer->mark)->buffer
7c23dd44
CY
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))))
9852377f 2058 {
d24ec09a 2059 EMACS_INT b = XMARKER (current_buffer->mark)->charpos;
413d18e7 2060 EMACS_INT e = PT;
746812d9
CY
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);
9852377f
CY
2065 }
2066
d206af14 2067 signal_before_change (start, end, preserve_ptr);
2f545eea 2068
56e1065e
JB
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
2f545eea 2078 Vdeactivate_mark = Qt;
b45433b3
JB
2079}
2080\f
d206af14
RS
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); \
dab0b04d 2092 unchain_marker (XMARKER (preserve_marker)); \
d206af14
RS
2093 }
2094
b86e0aaf
RS
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
4a181359 2107/* Set a variable to nil if an error occurred.
e6d3f090
SM
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). */
4a181359 2113Lisp_Object
971de7fb 2114reset_var_on_error (Lisp_Object val)
4a181359
SM
2115{
2116 if (NILP (XCDR (val)))
2117 Fset (XCAR (val), Qnil);
2118 return Qnil;
2119}
2120
eb8c3be9 2121/* Signal a change to the buffer immediately before it happens.
d206af14
RS
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. */
b45433b3 2126
c660b094 2127void
ae19ba7c 2128signal_before_change (EMACS_INT start_int, EMACS_INT end_int,
9628fed7 2129 EMACS_INT *preserve_ptr)
b45433b3 2130{
fb4ee5cd 2131 Lisp_Object start, end;
b86e0aaf 2132 Lisp_Object start_marker, end_marker;
d206af14 2133 Lisp_Object preserve_marker;
b86e0aaf 2134 struct gcpro gcpro1, gcpro2, gcpro3;
4a181359 2135 int count = SPECPDL_INDEX ();
fb4ee5cd 2136
fd16a4c6
KH
2137 if (inhibit_modification_hooks)
2138 return;
2139
fb4ee5cd
RS
2140 start = make_number (start_int);
2141 end = make_number (end_int);
d206af14 2142 preserve_marker = Qnil;
b86e0aaf
RS
2143 start_marker = Qnil;
2144 end_marker = Qnil;
2145 GCPRO3 (preserve_marker, start_marker, end_marker);
fb4ee5cd 2146
4a181359
SM
2147 specbind (Qinhibit_modification_hooks, Qt);
2148
b45433b3 2149 /* If buffer is unmodified, run a special hook for that case. */
9fbf87cd 2150 if (SAVE_MODIFF >= MODIFF
dbc4e1c1
JB
2151 && !NILP (Vfirst_change_hook)
2152 && !NILP (Vrun_hooks))
d206af14
RS
2153 {
2154 PRESERVE_VALUE;
b86e0aaf 2155 PRESERVE_START_END;
d206af14
RS
2156 call1 (Vrun_hooks, Qfirst_change_hook);
2157 }
dbc4e1c1 2158
3d1e2d9c 2159 /* Now run the before-change-functions if any. */
e45fb8bf
RS
2160 if (!NILP (Vbefore_change_functions))
2161 {
3d1e2d9c 2162 Lisp_Object args[3];
4a181359 2163 Lisp_Object rvoe_arg = Fcons (Qbefore_change_functions, Qnil);
3d1e2d9c 2164
d206af14 2165 PRESERVE_VALUE;
b86e0aaf 2166 PRESERVE_START_END;
d206af14 2167
4a181359
SM
2168 /* Mark before-change-functions to be reset to nil in case of error. */
2169 record_unwind_protect (reset_var_on_error, rvoe_arg);
3d1e2d9c
RS
2170
2171 /* Actually run the hook functions. */
2172 args[0] = Qbefore_change_functions;
b86e0aaf
RS
2173 args[1] = FETCH_START;
2174 args[2] = FETCH_END;
4a181359 2175 Frun_hook_with_args (3, args);
3d1e2d9c 2176
4a181359
SM
2177 /* There was no error: unarm the reset_on_error. */
2178 XSETCDR (rvoe_arg, Qt);
e45fb8bf 2179 }
d07c0804 2180
fbebdf81 2181 if (current_buffer->overlays_before || current_buffer->overlays_after)
d206af14
RS
2182 {
2183 PRESERVE_VALUE;
b86e0aaf
RS
2184 report_overlay_modification (FETCH_START, FETCH_END, 0,
2185 FETCH_START, FETCH_END, Qnil);
d206af14
RS
2186 }
2187
b86e0aaf
RS
2188 if (! NILP (start_marker))
2189 free_marker (start_marker);
2190 if (! NILP (end_marker))
2191 free_marker (end_marker);
d206af14
RS
2192 RESTORE_VALUE;
2193 UNGCPRO;
4a181359
SM
2194
2195 unbind_to (count, Qnil);
b45433b3
JB
2196}
2197
eb8c3be9 2198/* Signal a change immediately after it happens.
3be11131 2199 CHARPOS is the character position of the start of the changed text.
b45433b3
JB
2200 LENDEL is the number of characters of the text before the change.
2201 (Not the whole buffer; just the part that was changed.)
8b09e5d0
RS
2202 LENINS is the number of characters in that part of the text
2203 after the change. */
b45433b3 2204
c660b094 2205void
ae19ba7c 2206signal_after_change (EMACS_INT charpos, EMACS_INT lendel, EMACS_INT lenins)
b45433b3 2207{
4a181359 2208 int count = SPECPDL_INDEX ();
fd16a4c6
KH
2209 if (inhibit_modification_hooks)
2210 return;
2211
fb2e7d14
RS
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)
1675d086 2216 && NILP (Vbefore_change_functions)
fbebdf81
SM
2217 && !current_buffer->overlays_before
2218 && !current_buffer->overlays_after)
fb2e7d14
RS
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
3be11131
RS
2226 elt = Fcons (make_number (charpos - BEG),
2227 Fcons (make_number (Z - (charpos - lendel + lenins)),
fb2e7d14
RS
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
177c0ea7 2236 if (!NILP (combine_after_change_list))
fb2e7d14
RS
2237 Fcombine_after_change_execute ();
2238
4a181359
SM
2239 specbind (Qinhibit_modification_hooks, Qt);
2240
e45fb8bf
RS
2241 if (!NILP (Vafter_change_functions))
2242 {
3d1e2d9c 2243 Lisp_Object args[4];
4a181359
SM
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);
3d1e2d9c
RS
2248
2249 /* Actually run the hook functions. */
2250 args[0] = Qafter_change_functions;
3be11131
RS
2251 XSETFASTINT (args[1], charpos);
2252 XSETFASTINT (args[2], charpos + lenins);
3d1e2d9c 2253 XSETFASTINT (args[3], lendel);
4a181359 2254 Frun_hook_with_args (4, args);
3d1e2d9c 2255
4a181359
SM
2256 /* There was no error: unarm the reset_on_error. */
2257 XSETCDR (rvoe_arg, Qt);
e45fb8bf 2258 }
d07c0804 2259
fbebdf81 2260 if (current_buffer->overlays_before || current_buffer->overlays_after)
3be11131
RS
2261 report_overlay_modification (make_number (charpos),
2262 make_number (charpos + lenins),
d07c0804 2263 1,
3be11131
RS
2264 make_number (charpos),
2265 make_number (charpos + lenins),
d07c0804 2266 make_number (lendel));
c5ca0786
RS
2267
2268 /* After an insertion, call the text properties
2269 insert-behind-hooks or insert-in-front-hooks. */
2270 if (lendel == 0)
d6b81c0f
AS
2271 report_interval_modification (make_number (charpos),
2272 make_number (charpos + lenins));
4a181359
SM
2273
2274 unbind_to (count, Qnil);
b45433b3 2275}
fb2e7d14
RS
2276
2277Lisp_Object
971de7fb 2278Fcombine_after_change_execute_1 (Lisp_Object val)
fb2e7d14
RS
2279{
2280 Vcombine_after_change_calls = val;
2281 return val;
2282}
2283
2284DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
335c5470
PJ
2285 Scombine_after_change_execute, 0, 0, 0,
2286 doc: /* This function is for use internally in `combine-after-change-calls'. */)
5842a27b 2287 (void)
fb2e7d14 2288{
aed13378 2289 int count = SPECPDL_INDEX ();
ae19ba7c
SM
2290 EMACS_INT beg, end, change;
2291 EMACS_INT begpos, endpos;
fb2e7d14
RS
2292 Lisp_Object tail;
2293
101e446f
KH
2294 if (NILP (combine_after_change_list))
2295 return Qnil;
2296
c47a9ed1
CY
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
fb2e7d14
RS
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);
03699b14 2322 tail = XCDR (tail))
fb2e7d14 2323 {
e688a080 2324 Lisp_Object elt;
ae19ba7c 2325 EMACS_INT thisbeg, thisend, thischange;
fb2e7d14
RS
2326
2327 /* Extract the info from the next element. */
03699b14 2328 elt = XCAR (tail);
fb2e7d14
RS
2329 if (! CONSP (elt))
2330 continue;
03699b14 2331 thisbeg = XINT (XCAR (elt));
fb2e7d14 2332
03699b14 2333 elt = XCDR (elt);
fb2e7d14
RS
2334 if (! CONSP (elt))
2335 continue;
03699b14 2336 thisend = XINT (XCAR (elt));
fb2e7d14 2337
03699b14 2338 elt = XCDR (elt);
fb2e7d14
RS
2339 if (! CONSP (elt))
2340 continue;
03699b14 2341 thischange = XINT (XCAR (elt));
fb2e7d14
RS
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;
177c0ea7 2355
fb2e7d14
RS
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);
0ef71121 2364 update_compositions (begpos, endpos, CHECK_ALL);
fb2e7d14 2365
101e446f 2366 return unbind_to (count, Qnil);
fb2e7d14
RS
2367}
2368\f
dfcf069d 2369void
971de7fb 2370syms_of_insdel (void)
fb2e7d14
RS
2371{
2372 staticpro (&combine_after_change_list);
bf0bf758 2373 staticpro (&combine_after_change_buffer);
fb2e7d14 2374 combine_after_change_list = Qnil;
101e446f 2375 combine_after_change_buffer = Qnil;
fb2e7d14 2376
60ea6052 2377 DEFVAR_BOOL ("check-markers-debug-flag", &check_markers_debug_flag,
335c5470 2378 doc: /* Non-nil means enable debugging checks for invalid marker positions. */);
60ea6052 2379 check_markers_debug_flag = 0;
fb2e7d14 2380 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
335c5470 2381 doc: /* Used internally by the `combine-after-change-calls' macro. */);
fb2e7d14
RS
2382 Vcombine_after_change_calls = Qnil;
2383
7baf49cf 2384 DEFVAR_BOOL ("inhibit-modification-hooks", &inhibit_modification_hooks,
335c5470
PJ
2385 doc: /* Non-nil means don't run any of the hooks that respond to buffer changes.
2386This affects `before-change-functions' and `after-change-functions',
2387as well as hooks attached to text properties and overlays. */);
7baf49cf 2388 inhibit_modification_hooks = 0;
d67b4f80 2389 Qinhibit_modification_hooks = intern_c_string ("inhibit-modification-hooks");
27ea0af2 2390 staticpro (&Qinhibit_modification_hooks);
7baf49cf 2391
fb2e7d14
RS
2392 defsubr (&Scombine_after_change_execute);
2393}
6b61353c 2394