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