Mercurial > emacs
comparison src/insdel.c @ 20555:80a546059cbd
(move_gap): Use move_gap_both.
(move_gap_both): New function.
(gap_left, gap_right): Take both charpos and bytepos args.
(adjust_markers_gap_motion): Renamed from adjust_markers and simplified.
(adjust_markers_for_delete): New function.
(adjust_markers_for_insert): Take args in chars and bytes.
Also new arg BEFORE_MARKERS. One call does all marker updating
needed for any insert.
(adjust_point): Take 2 args and update PT and PT_BYTE.
(make_gap): Handle bytes vs chars.
(insert, insert_and_inherit): Handle bytes vs chars.
Pass new BEFORE_MARKERS arg to insert_1.
(insert_before_markers, insert_before_markers_and_inherit): Likewise.
(insert_from_string, insert_from_string_before_markers): Likewise.
(insert_from_buffer): Likewise.
(insert_1): Handle bytes vs chars. New arg BEFORE_MARKERS.
(insert_from_string_1, insert_from_buffer_1): Likewise.
(replace_range): Likewise.
(del_range_2): New subroutine, taken from del_range_1.
(del_range_1): Use del_range_2.
(del_range_byte, del_range_both): New functions.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Thu, 01 Jan 1998 07:03:19 +0000 |
parents | bc4c4e15a135 |
children | f0bacfbd9d47 |
comparison
equal
deleted
inserted
replaced
20554:2ea1c9492531 | 20555:80a546059cbd |
---|---|
1 /* Buffer insertion/deletion and gap motion for GNU Emacs. | 1 /* Buffer insertion/deletion and gap motion for GNU Emacs. |
2 Copyright (C) 1985, 1986, 1993, 1994, 1995 Free Software Foundation, Inc. | 2 Copyright (C) 1985, 86, 93, 94, 95, 1997 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GNU Emacs. | 4 This file is part of GNU Emacs. |
5 | 5 |
6 GNU Emacs is free software; you can redistribute it and/or modify | 6 GNU Emacs is free software; you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
31 #define NULL 0 | 31 #define NULL 0 |
32 #endif | 32 #endif |
33 | 33 |
34 #define min(x, y) ((x) < (y) ? (x) : (y)) | 34 #define min(x, y) ((x) < (y) ? (x) : (y)) |
35 | 35 |
36 static void insert_from_string_1 (); | 36 static void insert_from_string_1 P_ ((Lisp_Object, int, int, int, int, int)); |
37 static void insert_from_buffer_1 (); | 37 static void insert_from_buffer_1 (); |
38 static void gap_left (); | 38 static void gap_left P_ ((int, int, int)); |
39 static void gap_right (); | 39 static void gap_right P_ ((int, int)); |
40 static void adjust_markers (); | 40 static void adjust_markers_gap_motion P_ ((int, int, int)); |
41 static void adjust_point (); | 41 static void adjust_markers_for_insert P_ ((int, int, int, int, int)); |
42 static void adjust_markers_for_delete P_ ((int, int, int, int)); | |
43 static void adjust_point P_ ((int, int)); | |
42 | 44 |
43 Lisp_Object Fcombine_after_change_execute (); | 45 Lisp_Object Fcombine_after_change_execute (); |
44 | 46 |
45 /* Non-nil means don't call the after-change-functions right away, | 47 /* Non-nil means don't call the after-change-functions right away, |
46 just record an element in Vcombine_after_change_calls_list. */ | 48 just record an element in Vcombine_after_change_calls_list. */ |
59 Lisp_Object combine_after_change_list; | 61 Lisp_Object combine_after_change_list; |
60 | 62 |
61 /* Buffer which combine_after_change_list is about. */ | 63 /* Buffer which combine_after_change_list is about. */ |
62 Lisp_Object combine_after_change_buffer; | 64 Lisp_Object combine_after_change_buffer; |
63 | 65 |
64 /* Move gap to position `pos'. | 66 /* Move gap to position CHARPOS. |
65 Note that this can quit! */ | 67 Note that this can quit! */ |
66 | 68 |
67 void | 69 void |
68 move_gap (pos) | 70 move_gap (charpos) |
69 int pos; | 71 int charpos; |
70 { | 72 { |
71 if (pos < GPT) | 73 move_gap_both (charpos, charpos_to_bytepos (charpos)); |
72 gap_left (pos, 0); | 74 } |
73 else if (pos > GPT) | 75 |
74 gap_right (pos); | 76 /* Move gap to byte position BYTEPOS, which is also char position CHARPOS. |
75 } | 77 Note that this can quit! */ |
76 | 78 |
77 /* Move the gap to POS, which is less than the current GPT. | 79 void |
80 move_gap_both (charpos, bytepos) | |
81 int charpos, bytepos; | |
82 { | |
83 if (bytepos < GPT_BYTE) | |
84 gap_left (charpos, bytepos, 0); | |
85 else if (bytepos > GPT_BYTE) | |
86 gap_right (charpos, bytepos); | |
87 } | |
88 | |
89 /* Move the gap to a position less than the current GPT. | |
90 BYTEPOS describes the new position as a byte position, | |
91 and CHARPOS is the corresponding char position. | |
78 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */ | 92 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */ |
79 | 93 |
80 static void | 94 static void |
81 gap_left (pos, newgap) | 95 gap_left (charpos, bytepos, newgap) |
82 register int pos; | 96 register int charpos, bytepos; |
83 int newgap; | 97 int newgap; |
84 { | 98 { |
85 register unsigned char *to, *from; | 99 register unsigned char *to, *from; |
86 register int i; | 100 register int i; |
87 int new_s1; | 101 int new_s1; |
88 | 102 |
89 pos--; | |
90 | |
91 if (!newgap) | 103 if (!newgap) |
92 { | 104 { |
93 if (unchanged_modified == MODIFF | 105 if (unchanged_modified == MODIFF |
94 && overlay_unchanged_modified == OVERLAY_MODIFF) | 106 && overlay_unchanged_modified == OVERLAY_MODIFF) |
95 { | 107 { |
96 beg_unchanged = pos; | 108 beg_unchanged = charpos - BEG; |
97 end_unchanged = Z - pos - 1; | 109 end_unchanged = Z - charpos; |
98 } | 110 } |
99 else | 111 else |
100 { | 112 { |
101 if (Z - GPT < end_unchanged) | 113 if (Z - GPT < end_unchanged) |
102 end_unchanged = Z - GPT; | 114 end_unchanged = Z - GPT; |
103 if (pos < beg_unchanged) | 115 if (charpos < beg_unchanged) |
104 beg_unchanged = pos; | 116 beg_unchanged = charpos - BEG; |
105 } | 117 } |
106 } | 118 } |
107 | 119 |
108 i = GPT; | 120 i = GPT_BYTE; |
109 to = GAP_END_ADDR; | 121 to = GAP_END_ADDR; |
110 from = GPT_ADDR; | 122 from = GPT_ADDR; |
111 new_s1 = GPT - BEG; | 123 new_s1 = GPT_BYTE; |
112 | 124 |
113 /* Now copy the characters. To move the gap down, | 125 /* Now copy the characters. To move the gap down, |
114 copy characters up. */ | 126 copy characters up. */ |
115 | 127 |
116 while (1) | 128 while (1) |
117 { | 129 { |
118 /* I gets number of characters left to copy. */ | 130 /* I gets number of characters left to copy. */ |
119 i = new_s1 - pos; | 131 i = new_s1 - bytepos; |
120 if (i == 0) | 132 if (i == 0) |
121 break; | 133 break; |
122 /* If a quit is requested, stop copying now. | 134 /* If a quit is requested, stop copying now. |
123 Change POS to be where we have actually moved the gap to. */ | 135 Change BYTEPOS to be where we have actually moved the gap to. */ |
124 if (QUITP) | 136 if (QUITP) |
125 { | 137 { |
126 pos = new_s1; | 138 bytepos = new_s1; |
139 charpos = BYTE_TO_CHAR (bytepos); | |
127 break; | 140 break; |
128 } | 141 } |
129 /* Move at most 32000 chars before checking again for a quit. */ | 142 /* Move at most 32000 chars before checking again for a quit. */ |
130 if (i > 32000) | 143 if (i > 32000) |
131 i = 32000; | 144 i = 32000; |
151 while (--i >= 0) | 164 while (--i >= 0) |
152 *--to = *--from; | 165 *--to = *--from; |
153 } | 166 } |
154 } | 167 } |
155 | 168 |
156 /* Adjust markers, and buffer data structure, to put the gap at POS. | 169 /* Adjust markers, and buffer data structure, to put the gap at BYTEPOS. |
157 POS is where the loop above stopped, which may be what was specified | 170 BYTEPOS is where the loop above stopped, which may be what was specified |
158 or may be where a quit was detected. */ | 171 or may be where a quit was detected. */ |
159 adjust_markers (pos + 1, GPT, GAP_SIZE); | 172 adjust_markers_gap_motion (bytepos, GPT_BYTE, GAP_SIZE); |
160 GPT = pos + 1; | 173 GPT_BYTE = bytepos; |
174 GPT = charpos; | |
175 if (bytepos < charpos) | |
176 abort (); | |
161 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 177 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
162 QUIT; | 178 QUIT; |
163 } | 179 } |
164 | 180 |
181 /* Move the gap to a position greater than than the current GPT. | |
182 BYTEPOS describes the new position as a byte position, | |
183 and CHARPOS is the corresponding char position. */ | |
184 | |
165 static void | 185 static void |
166 gap_right (pos) | 186 gap_right (charpos, bytepos) |
167 register int pos; | 187 register int charpos, bytepos; |
168 { | 188 { |
169 register unsigned char *to, *from; | 189 register unsigned char *to, *from; |
170 register int i; | 190 register int i; |
171 int new_s1; | 191 int new_s1; |
172 | 192 |
173 pos--; | |
174 | |
175 if (unchanged_modified == MODIFF | 193 if (unchanged_modified == MODIFF |
176 && overlay_unchanged_modified == OVERLAY_MODIFF) | 194 && overlay_unchanged_modified == OVERLAY_MODIFF) |
177 | 195 { |
178 { | 196 beg_unchanged = charpos - BEG; |
179 beg_unchanged = pos; | 197 end_unchanged = Z - charpos; |
180 end_unchanged = Z - pos - 1; | |
181 } | 198 } |
182 else | 199 else |
183 { | 200 { |
184 if (Z - pos - 1 < end_unchanged) | 201 if (Z - charpos - 1 < end_unchanged) |
185 end_unchanged = Z - pos - 1; | 202 end_unchanged = Z - charpos; |
186 if (GPT - BEG < beg_unchanged) | 203 if (GPT - BEG < beg_unchanged) |
187 beg_unchanged = GPT - BEG; | 204 beg_unchanged = GPT - BEG; |
188 } | 205 } |
189 | 206 |
190 i = GPT; | 207 i = GPT_BYTE; |
191 from = GAP_END_ADDR; | 208 from = GAP_END_ADDR; |
192 to = GPT_ADDR; | 209 to = GPT_ADDR; |
193 new_s1 = GPT - 1; | 210 new_s1 = GPT_BYTE; |
194 | 211 |
195 /* Now copy the characters. To move the gap up, | 212 /* Now copy the characters. To move the gap up, |
196 copy characters down. */ | 213 copy characters down. */ |
197 | 214 |
198 while (1) | 215 while (1) |
199 { | 216 { |
200 /* I gets number of characters left to copy. */ | 217 /* I gets number of characters left to copy. */ |
201 i = pos - new_s1; | 218 i = bytepos - new_s1; |
202 if (i == 0) | 219 if (i == 0) |
203 break; | 220 break; |
204 /* If a quit is requested, stop copying now. | 221 /* If a quit is requested, stop copying now. |
205 Change POS to be where we have actually moved the gap to. */ | 222 Change BYTEPOS to be where we have actually moved the gap to. */ |
206 if (QUITP) | 223 if (QUITP) |
207 { | 224 { |
208 pos = new_s1; | 225 bytepos = new_s1; |
226 charpos = BYTE_TO_CHAR (bytepos); | |
209 break; | 227 break; |
210 } | 228 } |
211 /* Move at most 32000 chars before checking again for a quit. */ | 229 /* Move at most 32000 chars before checking again for a quit. */ |
212 if (i > 32000) | 230 if (i > 32000) |
213 i = 32000; | 231 i = 32000; |
233 while (--i >= 0) | 251 while (--i >= 0) |
234 *to++ = *from++; | 252 *to++ = *from++; |
235 } | 253 } |
236 } | 254 } |
237 | 255 |
238 adjust_markers (GPT + GAP_SIZE, pos + 1 + GAP_SIZE, - GAP_SIZE); | 256 adjust_markers_gap_motion (GPT_BYTE + GAP_SIZE, bytepos + GAP_SIZE, |
239 GPT = pos + 1; | 257 - GAP_SIZE); |
258 GPT = charpos; | |
259 GPT_BYTE = bytepos; | |
260 if (bytepos < charpos) | |
261 abort (); | |
240 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 262 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
241 QUIT; | 263 QUIT; |
242 } | 264 } |
243 | 265 |
244 /* Add AMOUNT to the position of every marker in the current buffer | 266 /* Add AMOUNT to the byte position of every marker in the current buffer |
245 whose current position is between FROM (exclusive) and TO (inclusive). | 267 whose current byte position is between FROM (exclusive) and TO (inclusive). |
246 | 268 |
247 Also, any markers past the outside of that interval, in the direction | 269 Also, any markers past the outside of that interval, in the direction |
248 of adjustment, are first moved back to the near end of the interval | 270 of adjustment, are first moved back to the near end of the interval |
249 and then adjusted by AMOUNT. | 271 and then adjusted by AMOUNT. |
250 | 272 |
251 When the latter adjustment is done, if AMOUNT is negative, | 273 When the latter adjustment is done, if AMOUNT is negative, |
252 we record the adjustment for undo. (This case happens only for | 274 we record the adjustment for undo. (This case happens only for |
253 deletion.) */ | 275 deletion.) |
276 | |
277 The markers' character positions are not altered, | |
278 because gap motion does not affect character positions. */ | |
279 | |
280 int adjust_markers_test; | |
254 | 281 |
255 static void | 282 static void |
256 adjust_markers (from, to, amount) | 283 adjust_markers_gap_motion (from, to, amount) |
257 register int from, to, amount; | 284 register int from, to, amount; |
258 { | 285 { |
259 Lisp_Object marker; | 286 Lisp_Object marker; |
260 register struct Lisp_Marker *m; | 287 register struct Lisp_Marker *m; |
261 register int mpos; | 288 register int mpos; |
267 m = XMARKER (marker); | 294 m = XMARKER (marker); |
268 mpos = m->bufpos; | 295 mpos = m->bufpos; |
269 if (amount > 0) | 296 if (amount > 0) |
270 { | 297 { |
271 if (mpos > to && mpos < to + amount) | 298 if (mpos > to && mpos < to + amount) |
272 mpos = to + amount; | 299 { |
300 if (adjust_markers_test) | |
301 abort (); | |
302 mpos = to + amount; | |
303 } | |
273 } | 304 } |
274 else | 305 else |
275 { | 306 { |
276 /* Here's the case where a marker is inside text being deleted. | 307 /* Here's the case where a marker is inside text being deleted. |
277 AMOUNT can be negative for gap motion, too, | 308 AMOUNT can be negative for gap motion, too, |
278 but then this range contains no markers. */ | 309 but then this range contains no markers. */ |
279 if (mpos > from + amount && mpos <= from) | 310 if (mpos > from + amount && mpos <= from) |
280 { | 311 { |
281 int before = mpos; | 312 if (adjust_markers_test) |
282 int after = from + amount; | 313 abort (); |
283 | 314 mpos = from + amount; |
284 mpos = after; | |
285 | |
286 /* Compute the before and after positions | |
287 as buffer positions. */ | |
288 if (before > GPT + GAP_SIZE) | |
289 before -= GAP_SIZE; | |
290 else if (before > GPT) | |
291 before = GPT; | |
292 | |
293 if (after > GPT + GAP_SIZE) | |
294 after -= GAP_SIZE; | |
295 else if (after > GPT) | |
296 after = GPT; | |
297 | |
298 record_marker_adjustment (marker, after - before); | |
299 } | 315 } |
300 } | 316 } |
301 if (mpos > from && mpos <= to) | 317 if (mpos > from && mpos <= to) |
302 mpos += amount; | 318 mpos += amount; |
303 m->bufpos = mpos; | 319 m->bufpos = mpos; |
304 marker = m->chain; | 320 marker = m->chain; |
305 } | 321 } |
306 } | 322 } |
307 | 323 |
308 /* Adjust markers whose insertion-type is t | 324 /* Adjust all markers for a deletion |
309 for an insertion of AMOUNT characters at POS. */ | 325 whose range in bytes is FROM_BYTE to TO_BYTE. |
326 The range in charpos is FROM to TO. | |
327 | |
328 This function assumes that the gap is adjacent to | |
329 or inside of the range being deleted. */ | |
310 | 330 |
311 static void | 331 static void |
312 adjust_markers_for_insert (pos, amount) | 332 adjust_markers_for_delete (from, from_byte, to, to_byte) |
313 register int pos, amount; | 333 register int from, from_byte, to, to_byte; |
334 { | |
335 Lisp_Object marker; | |
336 register struct Lisp_Marker *m; | |
337 register int charpos; | |
338 /* This is what GAP_SIZE will be when this deletion is finished. */ | |
339 int coming_gap_size = GAP_SIZE + to_byte - from_byte; | |
340 | |
341 marker = BUF_MARKERS (current_buffer); | |
342 | |
343 while (!NILP (marker)) | |
344 { | |
345 m = XMARKER (marker); | |
346 charpos = m->charpos; | |
347 | |
348 if (charpos > Z) | |
349 abort (); | |
350 | |
351 /* If the marker is after the deletion, | |
352 its bufpos needs no change because the deleted text | |
353 becomes gap; but its charpos needs to be decreased. */ | |
354 if (charpos > to) | |
355 m->charpos -= to - from; | |
356 | |
357 /* Here's the case where a marker is inside text being deleted. | |
358 We take advantage of the fact that the deletion is at the gap. */ | |
359 else if (charpos > from) | |
360 { | |
361 record_marker_adjustment (marker, from - charpos); | |
362 m->charpos = from; | |
363 /* The gap must be at or after FROM_BYTE when we do a deletion. */ | |
364 m->bufpos = from_byte; | |
365 } | |
366 | |
367 /* In a single-byte buffer, a marker's two positions must be equal. */ | |
368 if (Z == Z_BYTE) | |
369 { | |
370 register int i = m->bufpos; | |
371 | |
372 /* We use FROM_BYTE here instead of GPT_BYTE | |
373 because FROM_BYTE is where the gap will be after the deletion. */ | |
374 if (i > from_byte + coming_gap_size) | |
375 i -= coming_gap_size; | |
376 else if (i > from_byte) | |
377 i = from_byte; | |
378 | |
379 if (m->charpos != i) | |
380 abort (); | |
381 } | |
382 | |
383 marker = m->chain; | |
384 } | |
385 } | |
386 | |
387 /* Adjust markers for an insertion at CHARPOS / BYTEPOS | |
388 consisting of NCHARS chars, which are NBYTES bytes. | |
389 | |
390 We have to relocate the charpos of every marker that points | |
391 after the insertion (but not their bufpos). | |
392 | |
393 When a marker points at the insertion point, | |
394 we advance it if either its insertion-type is t | |
395 or BEFORE_MARKERS is true. */ | |
396 | |
397 static void | |
398 adjust_markers_for_insert (from, from_byte, to, to_byte, before_markers) | |
399 register int from, from_byte, to, to_byte, before_markers; | |
314 { | 400 { |
315 Lisp_Object marker; | 401 Lisp_Object marker; |
316 int adjusted = 0; | 402 int adjusted = 0; |
403 int nchars = to - from; | |
404 int nbytes = to_byte - from_byte; | |
317 | 405 |
318 marker = BUF_MARKERS (current_buffer); | 406 marker = BUF_MARKERS (current_buffer); |
319 | 407 |
320 while (!NILP (marker)) | 408 while (!NILP (marker)) |
321 { | 409 { |
322 register struct Lisp_Marker *m = XMARKER (marker); | 410 register struct Lisp_Marker *m = XMARKER (marker); |
323 if (m->insertion_type && m->bufpos == pos) | 411 if (m->bufpos == from_byte |
412 && (m->insertion_type || before_markers)) | |
324 { | 413 { |
325 m->bufpos += amount; | 414 m->bufpos += nbytes; |
326 adjusted = 1; | 415 m->charpos += nchars; |
416 if (m->insertion_type) | |
417 adjusted = 1; | |
327 } | 418 } |
419 else if (m->bufpos > from_byte) | |
420 m->charpos += nchars; | |
421 | |
422 /* In a single-byte buffer, a marker's two positions must be equal. */ | |
423 if (Z == Z_BYTE) | |
424 { | |
425 register int i = m->bufpos; | |
426 | |
427 if (i > GPT_BYTE + GAP_SIZE) | |
428 i -= GAP_SIZE; | |
429 else if (i > GPT_BYTE) | |
430 i = GPT_BYTE; | |
431 | |
432 if (m->charpos != i) | |
433 abort (); | |
434 } | |
435 | |
328 marker = m->chain; | 436 marker = m->chain; |
329 } | 437 } |
438 | |
439 /* Adjusting only markers whose insertion-type is t may result in | |
440 disordered overlays in the slot `overlays_before'. */ | |
330 if (adjusted) | 441 if (adjusted) |
331 /* Adjusting only markers whose insertion-type is t may result in | 442 fix_overlays_before (current_buffer, from, to); |
332 disordered overlays in the slot `overlays_before'. */ | 443 } |
333 fix_overlays_before (current_buffer, pos, pos + amount); | 444 |
334 } | 445 /* Adjust point for an insertion of NBYTES bytes, which are NCHARS characters. |
335 | 446 |
336 /* Add the specified amount to point. This is used only when the value | 447 This is used only when the value of point changes due to an insert |
337 of point changes due to an insert or delete; it does not represent | 448 or delete; it does not represent a conceptual change in point as a |
338 a conceptual change in point as a marker. In particular, point is | 449 marker. In particular, point is not crossing any interval |
339 not crossing any interval boundaries, so there's no need to use the | 450 boundaries, so there's no need to use the usual SET_PT macro. In |
340 usual SET_PT macro. In fact it would be incorrect to do so, because | 451 fact it would be incorrect to do so, because either the old or the |
341 either the old or the new value of point is out of sync with the | 452 new value of point is out of sync with the current set of |
342 current set of intervals. */ | 453 intervals. */ |
454 | |
343 static void | 455 static void |
344 adjust_point (amount) | 456 adjust_point (nchars, nbytes) |
345 int amount; | 457 int nchars, nbytes; |
346 { | 458 { |
347 BUF_PT (current_buffer) += amount; | 459 BUF_PT (current_buffer) += nchars; |
460 BUF_PT_BYTE (current_buffer) += nbytes; | |
461 | |
462 /* In a single-byte buffer, the two positions must be equal. */ | |
463 if (ZV == ZV_BYTE | |
464 && PT != PT_BYTE) | |
465 abort (); | |
348 } | 466 } |
349 | 467 |
350 /* Make the gap INCREMENT characters longer. */ | 468 /* Make the gap NBYTES_ADDED bytes longer. */ |
351 | 469 |
352 void | 470 void |
353 make_gap (increment) | 471 make_gap (nbytes_added) |
354 int increment; | 472 int nbytes_added; |
355 { | 473 { |
356 unsigned char *result; | 474 unsigned char *result; |
357 Lisp_Object tem; | 475 Lisp_Object tem; |
358 int real_gap_loc; | 476 int real_gap_loc; |
477 int real_gap_loc_byte; | |
359 int old_gap_size; | 478 int old_gap_size; |
360 | 479 |
361 /* If we have to get more space, get enough to last a while. */ | 480 /* If we have to get more space, get enough to last a while. */ |
362 increment += 2000; | 481 nbytes_added += 2000; |
363 | 482 |
364 /* Don't allow a buffer size that won't fit in an int | 483 /* Don't allow a buffer size that won't fit in an int |
365 even if it will fit in a Lisp integer. | 484 even if it will fit in a Lisp integer. |
366 That won't work because so many places use `int'. */ | 485 That won't work because so many places use `int'. */ |
367 | 486 |
368 if (Z - BEG + GAP_SIZE + increment | 487 if (Z_BYTE - BEG_BYTE + GAP_SIZE + nbytes_added |
369 >= ((unsigned) 1 << (min (BITS_PER_INT, VALBITS) - 1))) | 488 >= ((unsigned) 1 << (min (BITS_PER_INT, VALBITS) - 1))) |
370 error ("Buffer exceeds maximum size"); | 489 error ("Buffer exceeds maximum size"); |
371 | 490 |
372 BLOCK_INPUT; | 491 BLOCK_INPUT; |
373 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */ | 492 /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */ |
374 result = BUFFER_REALLOC (BEG_ADDR, (Z - BEG + GAP_SIZE + increment + 1)); | 493 result = BUFFER_REALLOC (BEG_ADDR, (Z_BYTE - BEG_BYTE |
494 + GAP_SIZE + nbytes_added + 1)); | |
375 | 495 |
376 if (result == 0) | 496 if (result == 0) |
377 { | 497 { |
378 UNBLOCK_INPUT; | 498 UNBLOCK_INPUT; |
379 memory_full (); | 499 memory_full (); |
386 /* Prevent quitting in move_gap. */ | 506 /* Prevent quitting in move_gap. */ |
387 tem = Vinhibit_quit; | 507 tem = Vinhibit_quit; |
388 Vinhibit_quit = Qt; | 508 Vinhibit_quit = Qt; |
389 | 509 |
390 real_gap_loc = GPT; | 510 real_gap_loc = GPT; |
511 real_gap_loc_byte = GPT_BYTE; | |
391 old_gap_size = GAP_SIZE; | 512 old_gap_size = GAP_SIZE; |
392 | 513 |
393 /* Call the newly allocated space a gap at the end of the whole space. */ | 514 /* Call the newly allocated space a gap at the end of the whole space. */ |
394 GPT = Z + GAP_SIZE; | 515 GPT = Z + GAP_SIZE; |
395 GAP_SIZE = increment; | 516 GAP_SIZE = nbytes_added; |
396 | 517 |
397 /* Move the new gap down to be consecutive with the end of the old one. | 518 /* Move the new gap down to be consecutive with the end of the old one. |
398 This adjusts the markers properly too. */ | 519 This adjusts the markers properly too. */ |
399 gap_left (real_gap_loc + old_gap_size, 1); | 520 gap_left (real_gap_loc + old_gap_size, real_gap_loc_byte + old_gap_size, 1); |
400 | 521 |
401 /* Now combine the two into one large gap. */ | 522 /* Now combine the two into one large gap. */ |
402 GAP_SIZE += old_gap_size; | 523 GAP_SIZE += old_gap_size; |
403 GPT = real_gap_loc; | 524 GPT = real_gap_loc; |
525 GPT_BYTE = real_gap_loc_byte; | |
404 | 526 |
405 /* Put an anchor. */ | 527 /* Put an anchor. */ |
406 *(Z_ADDR) = 0; | 528 *(Z_ADDR) = 0; |
407 | 529 |
408 Vinhibit_quit = tem; | 530 Vinhibit_quit = tem; |
411 /* Insert a string of specified length before point. | 533 /* Insert a string of specified length before point. |
412 DO NOT use this for the contents of a Lisp string or a Lisp buffer! | 534 DO NOT use this for the contents of a Lisp string or a Lisp buffer! |
413 prepare_to_modify_buffer could relocate the text. */ | 535 prepare_to_modify_buffer could relocate the text. */ |
414 | 536 |
415 void | 537 void |
416 insert (string, length) | 538 insert (string, nbytes) |
417 register unsigned char *string; | 539 register unsigned char *string; |
418 register length; | 540 register nbytes; |
419 { | 541 { |
420 if (length > 0) | 542 if (nbytes > 0) |
421 { | 543 { |
422 insert_1 (string, length, 0, 1); | 544 int opoint = PT; |
423 signal_after_change (PT-length, 0, length); | 545 insert_1 (string, nbytes, 0, 1, 0); |
424 } | 546 signal_after_change (opoint, 0, PT - opoint); |
425 } | 547 } |
426 | 548 } |
427 void | 549 |
428 insert_and_inherit (string, length) | 550 void |
551 insert_and_inherit (string, nbytes) | |
429 register unsigned char *string; | 552 register unsigned char *string; |
430 register length; | 553 register nbytes; |
431 { | 554 { |
432 if (length > 0) | 555 if (nbytes > 0) |
433 { | 556 { |
434 insert_1 (string, length, 1, 1); | 557 int opoint = PT; |
435 signal_after_change (PT-length, 0, length); | 558 insert_1 (string, nbytes, 1, 1, 0); |
436 } | 559 signal_after_change (opoint, 0, PT - opoint); |
437 } | 560 } |
438 | 561 } |
439 void | 562 |
440 insert_1 (string, length, inherit, prepare) | 563 /* Insert the character C before point */ |
564 | |
565 void | |
566 insert_char (c) | |
567 int c; | |
568 { | |
569 unsigned char workbuf[4], *str; | |
570 int len = CHAR_STRING (c, workbuf, str); | |
571 | |
572 insert (str, len); | |
573 } | |
574 | |
575 /* Insert the null-terminated string S before point */ | |
576 | |
577 void | |
578 insert_string (s) | |
579 char *s; | |
580 { | |
581 insert (s, strlen (s)); | |
582 } | |
583 | |
584 /* Like `insert' except that all markers pointing at the place where | |
585 the insertion happens are adjusted to point after it. | |
586 Don't use this function to insert part of a Lisp string, | |
587 since gc could happen and relocate it. */ | |
588 | |
589 void | |
590 insert_before_markers (string, nbytes) | |
591 unsigned char *string; | |
592 register int nbytes; | |
593 { | |
594 if (nbytes > 0) | |
595 { | |
596 int opoint = PT; | |
597 | |
598 insert_1 (string, nbytes, 0, 1, 1); | |
599 signal_after_change (opoint, 0, PT - opoint); | |
600 } | |
601 } | |
602 | |
603 void | |
604 insert_before_markers_and_inherit (string, nbytes) | |
605 unsigned char *string; | |
606 register int nbytes; | |
607 { | |
608 if (nbytes > 0) | |
609 { | |
610 int opoint = PT; | |
611 | |
612 insert_1 (string, nbytes, 1, 1, 1); | |
613 signal_after_change (opoint, 0, PT - opoint); | |
614 } | |
615 } | |
616 | |
617 /* Subroutine used by the insert functions above. */ | |
618 | |
619 void | |
620 insert_1 (string, nbytes, inherit, prepare, before_markers) | |
441 register unsigned char *string; | 621 register unsigned char *string; |
442 register int length; | 622 register int nbytes; |
443 int inherit, prepare; | 623 int inherit, prepare, before_markers; |
444 { | 624 { |
445 register Lisp_Object temp; | 625 register Lisp_Object temp; |
626 int nchars = chars_in_text (string, nbytes); | |
446 | 627 |
447 if (prepare) | 628 if (prepare) |
448 prepare_to_modify_buffer (PT, PT, NULL); | 629 prepare_to_modify_buffer (PT, PT, NULL); |
449 | 630 |
450 if (PT != GPT) | 631 if (PT != GPT) |
451 move_gap (PT); | 632 move_gap_both (PT, PT_BYTE); |
452 if (GAP_SIZE < length) | 633 if (GAP_SIZE < nbytes) |
453 make_gap (length - GAP_SIZE); | 634 make_gap (nbytes - GAP_SIZE); |
454 | 635 |
455 record_insert (PT, length); | 636 record_insert (PT, nchars); |
456 MODIFF++; | 637 MODIFF++; |
457 | 638 |
458 bcopy (string, GPT_ADDR, length); | 639 bcopy (string, GPT_ADDR, nbytes); |
459 | 640 |
460 #ifdef USE_TEXT_PROPERTIES | 641 #ifdef USE_TEXT_PROPERTIES |
461 if (BUF_INTERVALS (current_buffer) != 0) | 642 if (BUF_INTERVALS (current_buffer) != 0) |
462 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */ | 643 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */ |
463 offset_intervals (current_buffer, PT, length); | 644 offset_intervals (current_buffer, PT, nchars); |
464 #endif | 645 #endif |
465 | 646 |
466 GAP_SIZE -= length; | 647 GAP_SIZE -= nbytes; |
467 GPT += length; | 648 GPT += nchars; |
468 ZV += length; | 649 ZV += nchars; |
469 Z += length; | 650 Z += nchars; |
651 GPT_BYTE += nbytes; | |
652 ZV_BYTE += nbytes; | |
653 Z_BYTE += nbytes; | |
470 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 654 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
471 adjust_overlays_for_insert (PT, length); | 655 adjust_overlays_for_insert (PT, nchars); |
472 adjust_markers_for_insert (PT, length); | 656 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes, |
473 adjust_point (length); | 657 before_markers); |
658 adjust_point (nchars, nbytes); | |
659 | |
660 if (GPT_BYTE < GPT) | |
661 abort (); | |
474 | 662 |
475 #ifdef USE_TEXT_PROPERTIES | 663 #ifdef USE_TEXT_PROPERTIES |
476 if (!inherit && BUF_INTERVALS (current_buffer) != 0) | 664 if (!inherit && BUF_INTERVALS (current_buffer) != 0) |
477 Fset_text_properties (make_number (PT - length), make_number (PT), | 665 Fset_text_properties (make_number (PT - nchars), make_number (PT), |
478 Qnil, Qnil); | 666 Qnil, Qnil); |
479 #endif | 667 #endif |
480 } | 668 } |
481 | 669 |
482 /* Insert the part of the text of STRING, a Lisp object assumed to be | 670 /* Insert the part of the text of STRING, a Lisp object assumed to be |
483 of type string, consisting of the LENGTH characters starting at | 671 of type string, consisting of the LENGTH characters starting at |
484 position POS. If the text of STRING has properties, they are absorbed | 672 position POS. If the text of STRING has properties, they are absorbed |
485 into the buffer. | 673 into the buffer. |
486 | 674 |
494 register int pos, length; | 682 register int pos, length; |
495 int inherit; | 683 int inherit; |
496 { | 684 { |
497 if (length > 0) | 685 if (length > 0) |
498 { | 686 { |
499 insert_from_string_1 (string, pos, length, inherit); | 687 int opoint = PT; |
500 signal_after_change (PT-length, 0, length); | 688 int nchars = chars_in_text (XSTRING (string)->data + pos, length); |
501 } | 689 insert_from_string_1 (string, pos, length, nchars, inherit, 0); |
502 } | 690 signal_after_change (opoint, 0, PT - opoint); |
503 | 691 } |
504 static void | |
505 insert_from_string_1 (string, pos, length, inherit) | |
506 Lisp_Object string; | |
507 register int pos, length; | |
508 int inherit; | |
509 { | |
510 register Lisp_Object temp; | |
511 struct gcpro gcpro1; | |
512 | |
513 /* Make sure point-max won't overflow after this insertion. */ | |
514 XSETINT (temp, length + Z); | |
515 if (length + Z != XINT (temp)) | |
516 error ("maximum buffer size exceeded"); | |
517 | |
518 GCPRO1 (string); | |
519 prepare_to_modify_buffer (PT, PT, NULL); | |
520 | |
521 if (PT != GPT) | |
522 move_gap (PT); | |
523 if (GAP_SIZE < length) | |
524 make_gap (length - GAP_SIZE); | |
525 | |
526 record_insert (PT, length); | |
527 MODIFF++; | |
528 UNGCPRO; | |
529 | |
530 bcopy (XSTRING (string)->data, GPT_ADDR, length); | |
531 | |
532 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | |
533 offset_intervals (current_buffer, PT, length); | |
534 | |
535 GAP_SIZE -= length; | |
536 GPT += length; | |
537 ZV += length; | |
538 Z += length; | |
539 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | |
540 adjust_overlays_for_insert (PT, length); | |
541 adjust_markers_for_insert (PT, length); | |
542 | |
543 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | |
544 graft_intervals_into_buffer (XSTRING (string)->intervals, PT, length, | |
545 current_buffer, inherit); | |
546 | |
547 adjust_point (length); | |
548 } | |
549 | |
550 /* Insert text from BUF, starting at POS and having length LENGTH, into the | |
551 current buffer. If the text in BUF has properties, they are absorbed | |
552 into the current buffer. | |
553 | |
554 It does not work to use `insert' for this, because a malloc could happen | |
555 and relocate BUF's text before the bcopy happens. */ | |
556 | |
557 void | |
558 insert_from_buffer (buf, pos, length, inherit) | |
559 struct buffer *buf; | |
560 int pos, length; | |
561 int inherit; | |
562 { | |
563 if (length > 0) | |
564 { | |
565 insert_from_buffer_1 (buf, pos, length, inherit); | |
566 signal_after_change (PT-length, 0, length); | |
567 } | |
568 } | |
569 | |
570 static void | |
571 insert_from_buffer_1 (buf, pos, length, inherit) | |
572 struct buffer *buf; | |
573 int pos, length; | |
574 int inherit; | |
575 { | |
576 register Lisp_Object temp; | |
577 int chunk; | |
578 | |
579 /* Make sure point-max won't overflow after this insertion. */ | |
580 XSETINT (temp, length + Z); | |
581 if (length + Z != XINT (temp)) | |
582 error ("maximum buffer size exceeded"); | |
583 | |
584 prepare_to_modify_buffer (PT, PT, NULL); | |
585 | |
586 if (PT != GPT) | |
587 move_gap (PT); | |
588 if (GAP_SIZE < length) | |
589 make_gap (length - GAP_SIZE); | |
590 | |
591 record_insert (PT, length); | |
592 MODIFF++; | |
593 | |
594 if (pos < BUF_GPT (buf)) | |
595 { | |
596 chunk = BUF_GPT (buf) - pos; | |
597 if (chunk > length) | |
598 chunk = length; | |
599 bcopy (BUF_CHAR_ADDRESS (buf, pos), GPT_ADDR, chunk); | |
600 } | |
601 else | |
602 chunk = 0; | |
603 if (chunk < length) | |
604 bcopy (BUF_CHAR_ADDRESS (buf, pos + chunk), | |
605 GPT_ADDR + chunk, length - chunk); | |
606 | |
607 #ifdef USE_TEXT_PROPERTIES | |
608 if (BUF_INTERVALS (current_buffer) != 0) | |
609 offset_intervals (current_buffer, PT, length); | |
610 #endif | |
611 | |
612 GAP_SIZE -= length; | |
613 GPT += length; | |
614 ZV += length; | |
615 Z += length; | |
616 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | |
617 adjust_overlays_for_insert (PT, length); | |
618 adjust_markers_for_insert (PT, length); | |
619 adjust_point (length); | |
620 | |
621 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | |
622 graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf), | |
623 pos, length), | |
624 PT - length, length, current_buffer, inherit); | |
625 } | |
626 | |
627 /* Insert the character C before point */ | |
628 | |
629 void | |
630 insert_char (c) | |
631 int c; | |
632 { | |
633 unsigned char workbuf[4], *str; | |
634 int len = CHAR_STRING (c, workbuf, str); | |
635 | |
636 insert (str, len); | |
637 } | |
638 | |
639 /* Insert the null-terminated string S before point */ | |
640 | |
641 void | |
642 insert_string (s) | |
643 char *s; | |
644 { | |
645 insert (s, strlen (s)); | |
646 } | 692 } |
647 | 693 |
648 /* Like `insert' except that all markers pointing at the place where | 694 /* Like `insert' except that all markers pointing at the place where |
649 the insertion happens are adjusted to point after it. | 695 the insertion happens are adjusted to point after it. |
650 Don't use this function to insert part of a Lisp string, | 696 Don't use this function to insert part of a Lisp string, |
651 since gc could happen and relocate it. */ | 697 since gc could happen and relocate it. */ |
652 | 698 |
653 void | |
654 insert_before_markers (string, length) | |
655 unsigned char *string; | |
656 register int length; | |
657 { | |
658 if (length > 0) | |
659 { | |
660 register int opoint = PT; | |
661 insert_1 (string, length, 0, 1); | |
662 adjust_markers (opoint - 1, opoint, length); | |
663 signal_after_change (PT-length, 0, length); | |
664 } | |
665 } | |
666 | |
667 void | |
668 insert_before_markers_and_inherit (string, length) | |
669 unsigned char *string; | |
670 register int length; | |
671 { | |
672 if (length > 0) | |
673 { | |
674 register int opoint = PT; | |
675 insert_1 (string, length, 1, 1); | |
676 adjust_markers (opoint - 1, opoint, length); | |
677 signal_after_change (PT-length, 0, length); | |
678 } | |
679 } | |
680 | |
681 /* Insert part of a Lisp string, relocating markers after. */ | 699 /* Insert part of a Lisp string, relocating markers after. */ |
682 | 700 |
683 void | 701 void |
684 insert_from_string_before_markers (string, pos, length, inherit) | 702 insert_from_string_before_markers (string, pos, length, inherit) |
685 Lisp_Object string; | 703 Lisp_Object string; |
686 register int pos, length; | 704 register int pos, length; |
687 int inherit; | 705 int inherit; |
688 { | 706 { |
689 if (length > 0) | 707 if (length > 0) |
690 { | 708 { |
691 register int opoint = PT; | 709 int opoint = PT; |
692 insert_from_string_1 (string, pos, length, inherit); | 710 int nchars = chars_in_text (XSTRING (string)->data + pos, length); |
693 adjust_markers (opoint - 1, opoint, length); | 711 insert_from_string_1 (string, pos, length, nchars, inherit, 1); |
694 signal_after_change (PT-length, 0, length); | 712 signal_after_change (opoint, 0, PT - opoint); |
695 } | 713 } |
714 } | |
715 | |
716 /* Subroutine of the insertion functions above. */ | |
717 | |
718 static void | |
719 insert_from_string_1 (string, pos, nbytes, nchars, inherit, before_markers) | |
720 Lisp_Object string; | |
721 register int pos, nbytes, nchars; | |
722 int inherit, before_markers; | |
723 { | |
724 register Lisp_Object temp; | |
725 struct gcpro gcpro1; | |
726 | |
727 /* Make sure point-max won't overflow after this insertion. */ | |
728 XSETINT (temp, nbytes + Z_BYTE); | |
729 if (nbytes + Z_BYTE != XINT (temp)) | |
730 error ("Maximum buffer size exceeded"); | |
731 | |
732 GCPRO1 (string); | |
733 prepare_to_modify_buffer (PT, PT, NULL); | |
734 | |
735 if (PT != GPT) | |
736 move_gap_both (PT, PT_BYTE); | |
737 if (GAP_SIZE < nbytes) | |
738 make_gap (nbytes - GAP_SIZE); | |
739 | |
740 record_insert (PT, nchars); | |
741 MODIFF++; | |
742 UNGCPRO; | |
743 | |
744 bcopy (XSTRING (string)->data, GPT_ADDR, nbytes); | |
745 | |
746 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | |
747 offset_intervals (current_buffer, PT, nchars); | |
748 | |
749 GAP_SIZE -= nbytes; | |
750 GPT += nchars; | |
751 ZV += nchars; | |
752 Z += nchars; | |
753 GPT_BYTE += nbytes; | |
754 ZV_BYTE += nbytes; | |
755 Z_BYTE += nbytes; | |
756 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | |
757 adjust_overlays_for_insert (PT, nchars); | |
758 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes, | |
759 before_markers); | |
760 | |
761 if (GPT_BYTE < GPT) | |
762 abort (); | |
763 | |
764 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | |
765 graft_intervals_into_buffer (XSTRING (string)->intervals, PT, nchars, | |
766 current_buffer, inherit); | |
767 | |
768 adjust_point (nchars, nbytes); | |
696 } | 769 } |
697 | 770 |
698 /* Replace the text from FROM to TO with NEW, | 771 /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the |
772 current buffer. If the text in BUF has properties, they are absorbed | |
773 into the current buffer. | |
774 | |
775 It does not work to use `insert' for this, because a malloc could happen | |
776 and relocate BUF's text before the bcopy happens. */ | |
777 | |
778 void | |
779 insert_from_buffer (buf, charpos, nchars, inherit) | |
780 struct buffer *buf; | |
781 int charpos, nchars; | |
782 int inherit; | |
783 { | |
784 if (nchars > 0) | |
785 { | |
786 int opoint = PT; | |
787 | |
788 insert_from_buffer_1 (buf, charpos, nchars, inherit); | |
789 signal_after_change (opoint, 0, PT - opoint); | |
790 } | |
791 } | |
792 | |
793 static void | |
794 insert_from_buffer_1 (buf, from, nchars, inherit) | |
795 struct buffer *buf; | |
796 int from, nchars; | |
797 int inherit; | |
798 { | |
799 register Lisp_Object temp; | |
800 int chunk; | |
801 int from_byte = buf_charpos_to_bytepos (buf, from); | |
802 int to_byte = buf_charpos_to_bytepos (buf, from + nchars); | |
803 int nbytes = to_byte - from_byte; | |
804 | |
805 /* Make sure point-max won't overflow after this insertion. */ | |
806 XSETINT (temp, nbytes + Z); | |
807 if (nbytes + Z != XINT (temp)) | |
808 error ("Maximum buffer size exceeded"); | |
809 | |
810 prepare_to_modify_buffer (PT, PT, NULL); | |
811 | |
812 if (PT != GPT) | |
813 move_gap_both (PT, PT_BYTE); | |
814 if (GAP_SIZE < nbytes) | |
815 make_gap (nbytes - GAP_SIZE); | |
816 | |
817 record_insert (PT, nchars); | |
818 MODIFF++; | |
819 | |
820 if (from < BUF_GPT (buf)) | |
821 { | |
822 chunk = BUF_GPT_BYTE (buf) - from_byte; | |
823 if (chunk > nbytes) | |
824 chunk = nbytes; | |
825 bcopy (BUF_BYTE_ADDRESS (buf, from_byte), GPT_ADDR, chunk); | |
826 } | |
827 else | |
828 chunk = 0; | |
829 if (chunk < nbytes) | |
830 bcopy (BUF_BYTE_ADDRESS (buf, from_byte + chunk), | |
831 GPT_ADDR + chunk, nbytes - chunk); | |
832 | |
833 #ifdef USE_TEXT_PROPERTIES | |
834 if (BUF_INTERVALS (current_buffer) != 0) | |
835 offset_intervals (current_buffer, PT, nchars); | |
836 #endif | |
837 | |
838 GAP_SIZE -= nbytes; | |
839 GPT += nchars; | |
840 ZV += nchars; | |
841 Z += nchars; | |
842 GPT_BYTE += nbytes; | |
843 ZV_BYTE += nbytes; | |
844 Z_BYTE += nbytes; | |
845 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | |
846 adjust_overlays_for_insert (PT, nchars); | |
847 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes, 0); | |
848 adjust_point (nchars, nbytes); | |
849 | |
850 if (GPT_BYTE < GPT) | |
851 abort (); | |
852 | |
853 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | |
854 graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf), | |
855 from, nchars), | |
856 PT - nchars, nchars, | |
857 current_buffer, inherit); | |
858 } | |
859 | |
860 /* Replace the text from character positions FROM to TO with NEW, | |
699 If PREPARE is nonzero, call prepare_to_modify_buffer. | 861 If PREPARE is nonzero, call prepare_to_modify_buffer. |
700 If INHERIT, the newly inserted text should inherit text properties | 862 If INHERIT, the newly inserted text should inherit text properties |
701 from the surrounding non-deleted text. */ | 863 from the surrounding non-deleted text. */ |
702 | 864 |
703 /* Note that this does not yet handle markers quite right. | 865 /* Note that this does not yet handle markers quite right. |
708 void | 870 void |
709 replace_range (from, to, new, prepare, inherit) | 871 replace_range (from, to, new, prepare, inherit) |
710 Lisp_Object new; | 872 Lisp_Object new; |
711 int from, to, prepare, inherit; | 873 int from, to, prepare, inherit; |
712 { | 874 { |
713 int numdel; | 875 int insbytes = XSTRING (new)->size; |
714 int inslen = XSTRING (new)->size; | 876 int inschars; |
877 int from_byte, to_byte; | |
878 int nbytes_del, nchars_del; | |
715 register Lisp_Object temp; | 879 register Lisp_Object temp; |
716 struct gcpro gcpro1; | 880 struct gcpro gcpro1; |
717 | 881 |
718 GCPRO1 (new); | 882 GCPRO1 (new); |
719 | 883 |
721 { | 885 { |
722 int range_length = to - from; | 886 int range_length = to - from; |
723 prepare_to_modify_buffer (from, to, &from); | 887 prepare_to_modify_buffer (from, to, &from); |
724 to = from + range_length; | 888 to = from + range_length; |
725 } | 889 } |
890 | |
891 UNGCPRO; | |
726 | 892 |
727 /* Make args be valid */ | 893 /* Make args be valid */ |
728 if (from < BEGV) | 894 if (from < BEGV) |
729 from = BEGV; | 895 from = BEGV; |
730 if (to > ZV) | 896 if (to > ZV) |
731 to = ZV; | 897 to = ZV; |
732 | 898 |
733 UNGCPRO; | 899 from_byte = CHAR_TO_BYTE (from); |
734 | 900 to_byte = CHAR_TO_BYTE (to); |
735 numdel = to - from; | 901 |
902 nchars_del = to - from; | |
903 nbytes_del = to_byte - from_byte; | |
904 | |
905 if (nbytes_del <= 0 && insbytes == 0) | |
906 return; | |
736 | 907 |
737 /* Make sure point-max won't overflow after this insertion. */ | 908 /* Make sure point-max won't overflow after this insertion. */ |
738 XSETINT (temp, Z - numdel + inslen); | 909 XSETINT (temp, Z_BYTE - nbytes_del + insbytes); |
739 if (Z - numdel + inslen != XINT (temp)) | 910 if (Z_BYTE - nbytes_del + insbytes != XINT (temp)) |
740 error ("maximum buffer size exceeded"); | 911 error ("Maximum buffer size exceeded"); |
741 | 912 |
742 if (numdel <= 0 && inslen == 0) | 913 inschars = XINT (Fchars_in_string (new)); |
743 return; | |
744 | 914 |
745 GCPRO1 (new); | 915 GCPRO1 (new); |
746 | 916 |
747 /* Make sure the gap is somewhere in or next to what we are deleting. */ | 917 /* Make sure the gap is somewhere in or next to what we are deleting. */ |
748 if (from > GPT) | 918 if (from > GPT) |
749 gap_right (from); | 919 gap_right (from, from_byte); |
750 if (to < GPT) | 920 if (to < GPT) |
751 gap_left (to, 0); | 921 gap_left (to, to_byte, 0); |
752 | 922 |
753 /* Relocate all markers pointing into the new, larger gap | 923 /* Relocate all markers pointing into the new, larger gap |
754 to point at the end of the text before the gap. | 924 to point at the end of the text before the gap. |
755 This has to be done before recording the deletion, | 925 Do this before recording the deletion, |
756 so undo handles this after reinserting the text. */ | 926 so that undo handles this after reinserting the text. */ |
757 adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE); | 927 adjust_markers_for_delete (from, from_byte, to, to_byte); |
758 | 928 |
759 record_delete (from, numdel); | 929 record_delete (from, nchars_del); |
760 | 930 |
761 GAP_SIZE += numdel; | 931 GAP_SIZE += nbytes_del; |
762 ZV -= numdel; | 932 ZV -= nchars_del; |
763 Z -= numdel; | 933 Z -= nchars_del; |
934 ZV_BYTE -= nbytes_del; | |
935 Z_BYTE -= nbytes_del; | |
764 GPT = from; | 936 GPT = from; |
937 GPT_BYTE = from_byte; | |
765 *(GPT_ADDR) = 0; /* Put an anchor. */ | 938 *(GPT_ADDR) = 0; /* Put an anchor. */ |
939 | |
940 if (GPT_BYTE < GPT) | |
941 abort (); | |
766 | 942 |
767 if (GPT - BEG < beg_unchanged) | 943 if (GPT - BEG < beg_unchanged) |
768 beg_unchanged = GPT - BEG; | 944 beg_unchanged = GPT - BEG; |
769 if (Z - GPT < end_unchanged) | 945 if (Z - GPT < end_unchanged) |
770 end_unchanged = Z - GPT; | 946 end_unchanged = Z - GPT; |
771 | 947 |
772 if (GAP_SIZE < inslen) | 948 if (GAP_SIZE < insbytes) |
773 make_gap (inslen - GAP_SIZE); | 949 make_gap (insbytes - GAP_SIZE); |
774 | 950 |
775 record_insert (from, inslen); | 951 record_insert (from, inschars); |
776 | 952 |
777 bcopy (XSTRING (new)->data, GPT_ADDR, inslen); | 953 bcopy (XSTRING (new)->data, GPT_ADDR, insbytes); |
778 | 954 |
779 /* Relocate point as if it were a marker. */ | 955 /* Relocate point as if it were a marker. */ |
780 if (from < PT) | 956 if (from < PT) |
781 adjust_point (from + inslen - (PT < to ? PT : to)); | 957 adjust_point (from + inschars - (PT < to ? PT : to), |
958 (from_byte + insbytes | |
959 - (PT_BYTE < to_byte ? PT_BYTE : to_byte))); | |
782 | 960 |
783 #ifdef USE_TEXT_PROPERTIES | 961 #ifdef USE_TEXT_PROPERTIES |
784 offset_intervals (current_buffer, PT, inslen - numdel); | 962 offset_intervals (current_buffer, PT, inschars - nchars_del); |
785 #endif | 963 #endif |
786 | 964 |
787 GAP_SIZE -= inslen; | 965 GAP_SIZE -= insbytes; |
788 GPT += inslen; | 966 GPT += inschars; |
789 ZV += inslen; | 967 ZV += inschars; |
790 Z += inslen; | 968 Z += inschars; |
969 GPT_BYTE += insbytes; | |
970 ZV_BYTE += insbytes; | |
971 ZV_BYTE += insbytes; | |
791 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 972 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
973 | |
974 if (GPT_BYTE < GPT) | |
975 abort (); | |
792 | 976 |
793 /* Adjust the overlay center as needed. This must be done after | 977 /* Adjust the overlay center as needed. This must be done after |
794 adjusting the markers that bound the overlays. */ | 978 adjusting the markers that bound the overlays. */ |
795 adjust_overlays_for_delete (from, numdel); | 979 adjust_overlays_for_delete (from, nchars_del); |
796 adjust_overlays_for_insert (from, inslen); | 980 adjust_overlays_for_insert (from, inschars); |
797 adjust_markers_for_insert (from, inslen); | 981 adjust_markers_for_insert (from, from_byte, from + inschars, |
982 from_byte + insbytes, 0); | |
798 | 983 |
799 #ifdef USE_TEXT_PROPERTIES | 984 #ifdef USE_TEXT_PROPERTIES |
800 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 985 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ |
801 graft_intervals_into_buffer (XSTRING (new)->intervals, from, inslen, | 986 graft_intervals_into_buffer (XSTRING (new)->intervals, from, |
802 current_buffer, inherit); | 987 inschars, current_buffer, inherit); |
803 #endif | 988 #endif |
804 | 989 |
805 if (inslen == 0) | 990 if (insbytes == 0) |
806 evaporate_overlays (from); | 991 evaporate_overlays (from); |
807 | 992 |
808 MODIFF++; | 993 MODIFF++; |
809 UNGCPRO; | 994 UNGCPRO; |
810 | 995 |
811 signal_after_change (from, numdel, inslen); | 996 signal_after_change (from, nchars_del, inschars); |
812 } | 997 } |
813 | 998 |
814 /* Delete characters in current buffer | 999 /* Delete characters in current buffer |
815 from FROM up to (but not including) TO. */ | 1000 from FROM up to (but not including) TO. |
1001 If TO comes before FROM, we delete nothing. */ | |
816 | 1002 |
817 void | 1003 void |
818 del_range (from, to) | 1004 del_range (from, to) |
819 register int from, to; | 1005 register int from, to; |
820 { | 1006 { |
825 | 1011 |
826 void | 1012 void |
827 del_range_1 (from, to, prepare) | 1013 del_range_1 (from, to, prepare) |
828 int from, to, prepare; | 1014 int from, to, prepare; |
829 { | 1015 { |
830 register int numdel; | 1016 int from_byte, to_byte; |
831 | |
832 if (prepare) | |
833 { | |
834 int range_length = to - from; | |
835 prepare_to_modify_buffer (from, to, &from); | |
836 to = from + range_length; | |
837 } | |
838 | 1017 |
839 /* Make args be valid */ | 1018 /* Make args be valid */ |
840 if (from < BEGV) | 1019 if (from < BEGV) |
841 from = BEGV; | 1020 from = BEGV; |
842 if (to > ZV) | 1021 if (to > ZV) |
843 to = ZV; | 1022 to = ZV; |
844 | 1023 |
845 if ((numdel = to - from) <= 0) | 1024 if (to <= from) |
846 return; | 1025 return; |
1026 | |
1027 if (prepare) | |
1028 { | |
1029 int range_length = to - from; | |
1030 prepare_to_modify_buffer (from, to, &from); | |
1031 to = from + range_length; | |
1032 } | |
1033 | |
1034 from_byte = CHAR_TO_BYTE (from); | |
1035 to_byte = CHAR_TO_BYTE (to); | |
1036 | |
1037 del_range_2 (from, to, from_byte, to_byte); | |
1038 } | |
1039 | |
1040 /* Like del_range_1 but args are byte positions, not char positions. */ | |
1041 | |
1042 void | |
1043 del_range_byte (from_byte, to_byte, prepare) | |
1044 int from_byte, to_byte, prepare; | |
1045 { | |
1046 int from, to; | |
1047 | |
1048 /* Make args be valid */ | |
1049 if (from_byte < BEGV_BYTE) | |
1050 from_byte = BEGV_BYTE; | |
1051 if (to_byte > ZV_BYTE) | |
1052 to_byte = ZV_BYTE; | |
1053 | |
1054 if (to_byte <= from_byte) | |
1055 return; | |
1056 | |
1057 from = BYTE_TO_CHAR (from_byte); | |
1058 to = BYTE_TO_CHAR (to_byte); | |
1059 | |
1060 if (prepare) | |
1061 { | |
1062 int old_from = from, old_to = Z - to; | |
1063 int range_length = to - from; | |
1064 prepare_to_modify_buffer (from, to, &from); | |
1065 to = from + range_length; | |
1066 | |
1067 if (old_from != from) | |
1068 from_byte = CHAR_TO_BYTE (from); | |
1069 if (old_to == Z - to) | |
1070 to_byte = CHAR_TO_BYTE (to); | |
1071 } | |
1072 | |
1073 del_range_2 (from, to, from_byte, to_byte); | |
1074 } | |
1075 | |
1076 /* Like del_range_1, but positions are specified both as charpos | |
1077 and bytepos. */ | |
1078 | |
1079 void | |
1080 del_range_both (from, to, from_byte, to_byte, prepare) | |
1081 int from, to, from_byte, to_byte, prepare; | |
1082 { | |
1083 /* Make args be valid */ | |
1084 if (from_byte < BEGV_BYTE) | |
1085 from_byte = BEGV_BYTE; | |
1086 if (to_byte > ZV_BYTE) | |
1087 to_byte = ZV_BYTE; | |
1088 | |
1089 if (to_byte <= from_byte) | |
1090 return; | |
1091 | |
1092 if (from < BEGV) | |
1093 from = BEGV; | |
1094 if (to > ZV) | |
1095 to = ZV; | |
1096 | |
1097 if (prepare) | |
1098 { | |
1099 int old_from = from, old_to = Z - to; | |
1100 int range_length = to - from; | |
1101 prepare_to_modify_buffer (from, to, &from); | |
1102 to = from + range_length; | |
1103 | |
1104 if (old_from != from) | |
1105 from_byte = CHAR_TO_BYTE (from); | |
1106 if (old_to == Z - to) | |
1107 to_byte = CHAR_TO_BYTE (to); | |
1108 } | |
1109 | |
1110 del_range_2 (from, to, from_byte, to_byte); | |
1111 } | |
1112 | |
1113 /* Delete a range of text, specified both as character positions | |
1114 and byte positions. FROM and TO are character positions, | |
1115 while FROM_BYTE and TO_BYTE are byte positions. */ | |
1116 | |
1117 void | |
1118 del_range_2 (from, to, from_byte, to_byte) | |
1119 int from, to, from_byte, to_byte; | |
1120 { | |
1121 register int nbytes_del, nchars_del; | |
1122 | |
1123 nchars_del = to - from; | |
1124 nbytes_del = to_byte - from_byte; | |
847 | 1125 |
848 /* Make sure the gap is somewhere in or next to what we are deleting. */ | 1126 /* Make sure the gap is somewhere in or next to what we are deleting. */ |
849 if (from > GPT) | 1127 if (from > GPT) |
850 gap_right (from); | 1128 gap_right (from, from_byte); |
851 if (to < GPT) | 1129 if (to < GPT) |
852 gap_left (to, 0); | 1130 gap_left (to, to_byte, 0); |
853 | 1131 |
854 /* Relocate all markers pointing into the new, larger gap | 1132 /* Relocate all markers pointing into the new, larger gap |
855 to point at the end of the text before the gap. | 1133 to point at the end of the text before the gap. |
856 This has to be done before recording the deletion, | 1134 Do this before recording the deletion, |
857 so undo handles this after reinserting the text. */ | 1135 so that undo handles this after reinserting the text. */ |
858 adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE); | 1136 adjust_markers_for_delete (from, from_byte, to, to_byte); |
859 | 1137 |
860 record_delete (from, numdel); | 1138 record_delete (from, nchars_del); |
861 MODIFF++; | 1139 MODIFF++; |
862 | 1140 |
863 /* Relocate point as if it were a marker. */ | 1141 /* Relocate point as if it were a marker. */ |
864 if (from < PT) | 1142 if (from < PT) |
865 adjust_point (from - (PT < to ? PT : to)); | 1143 adjust_point (from - (PT < to ? PT : to), |
1144 from_byte - (PT_BYTE < to_byte ? PT_BYTE : to_byte)); | |
866 | 1145 |
867 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 1146 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ |
868 offset_intervals (current_buffer, from, - numdel); | 1147 offset_intervals (current_buffer, from, - nchars_del); |
869 | 1148 |
870 /* Adjust the overlay center as needed. This must be done after | 1149 /* Adjust the overlay center as needed. This must be done after |
871 adjusting the markers that bound the overlays. */ | 1150 adjusting the markers that bound the overlays. */ |
872 adjust_overlays_for_delete (from, numdel); | 1151 adjust_overlays_for_delete (from_byte, nchars_del); |
873 | 1152 |
874 GAP_SIZE += numdel; | 1153 GAP_SIZE += nbytes_del; |
875 ZV -= numdel; | 1154 ZV_BYTE -= nbytes_del; |
876 Z -= numdel; | 1155 Z_BYTE -= nbytes_del; |
1156 ZV -= nchars_del; | |
1157 Z -= nchars_del; | |
877 GPT = from; | 1158 GPT = from; |
1159 GPT_BYTE = from_byte; | |
878 *(GPT_ADDR) = 0; /* Put an anchor. */ | 1160 *(GPT_ADDR) = 0; /* Put an anchor. */ |
1161 | |
1162 if (GPT_BYTE < GPT) | |
1163 abort (); | |
879 | 1164 |
880 if (GPT - BEG < beg_unchanged) | 1165 if (GPT - BEG < beg_unchanged) |
881 beg_unchanged = GPT - BEG; | 1166 beg_unchanged = GPT - BEG; |
882 if (Z - GPT < end_unchanged) | 1167 if (Z - GPT < end_unchanged) |
883 end_unchanged = Z - GPT; | 1168 end_unchanged = Z - GPT; |
884 | 1169 |
885 evaporate_overlays (from); | 1170 evaporate_overlays (from); |
886 signal_after_change (from, numdel, 0); | 1171 signal_after_change (from, nchars_del, 0); |
887 } | 1172 } |
888 | 1173 |
889 /* Call this if you're about to change the region of BUFFER from START | 1174 /* Call this if you're about to change the region of BUFFER from |
890 to END. This checks the read-only properties of the region, calls | 1175 character positions START to END. This checks the read-only |
891 the necessary modification hooks, and warns the next redisplay that | 1176 properties of the region, calls the necessary modification hooks, |
892 it should pay attention to that area. */ | 1177 and warns the next redisplay that it should pay attention to that |
1178 area. */ | |
1179 | |
893 void | 1180 void |
894 modify_region (buffer, start, end) | 1181 modify_region (buffer, start, end) |
895 struct buffer *buffer; | 1182 struct buffer *buffer; |
896 int start, end; | 1183 int start, end; |
897 { | 1184 { |
919 | 1206 |
920 if (buffer != old_buffer) | 1207 if (buffer != old_buffer) |
921 set_buffer_internal (old_buffer); | 1208 set_buffer_internal (old_buffer); |
922 } | 1209 } |
923 | 1210 |
924 /* Check that it is okay to modify the buffer between START and END. | 1211 /* Check that it is okay to modify the buffer between START and END, |
1212 which are char positions. | |
1213 | |
925 Run the before-change-function, if any. If intervals are in use, | 1214 Run the before-change-function, if any. If intervals are in use, |
926 verify that the text to be modified is not read-only, and call | 1215 verify that the text to be modified is not read-only, and call |
927 any modification properties the text may have. | 1216 any modification properties the text may have. |
928 | 1217 |
929 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR | 1218 If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR |
1101 RESTORE_VALUE; | 1390 RESTORE_VALUE; |
1102 UNGCPRO; | 1391 UNGCPRO; |
1103 } | 1392 } |
1104 | 1393 |
1105 /* Signal a change immediately after it happens. | 1394 /* Signal a change immediately after it happens. |
1106 POS is the address of the start of the changed text. | 1395 CHARPOS is the character position of the start of the changed text. |
1107 LENDEL is the number of characters of the text before the change. | 1396 LENDEL is the number of characters of the text before the change. |
1108 (Not the whole buffer; just the part that was changed.) | 1397 (Not the whole buffer; just the part that was changed.) |
1109 LENINS is the number of characters in that part of the text | 1398 LENINS is the number of characters in that part of the text |
1110 after the change. */ | 1399 after the change. */ |
1111 | 1400 |
1112 void | 1401 void |
1113 signal_after_change (pos, lendel, lenins) | 1402 signal_after_change (charpos, lendel, lenins) |
1114 int pos, lendel, lenins; | 1403 int charpos, lendel, lenins; |
1115 { | 1404 { |
1116 /* If we are deferring calls to the after-change functions | 1405 /* If we are deferring calls to the after-change functions |
1117 and there are no before-change functions, | 1406 and there are no before-change functions, |
1118 just record the args that we were going to use. */ | 1407 just record the args that we were going to use. */ |
1119 if (! NILP (Vcombine_after_change_calls) | 1408 if (! NILP (Vcombine_after_change_calls) |
1125 | 1414 |
1126 if (!NILP (combine_after_change_list) | 1415 if (!NILP (combine_after_change_list) |
1127 && current_buffer != XBUFFER (combine_after_change_buffer)) | 1416 && current_buffer != XBUFFER (combine_after_change_buffer)) |
1128 Fcombine_after_change_execute (); | 1417 Fcombine_after_change_execute (); |
1129 | 1418 |
1130 elt = Fcons (make_number (pos - BEG), | 1419 elt = Fcons (make_number (charpos - BEG), |
1131 Fcons (make_number (Z - (pos - lendel + lenins)), | 1420 Fcons (make_number (Z - (charpos - lendel + lenins)), |
1132 Fcons (make_number (lenins - lendel), Qnil))); | 1421 Fcons (make_number (lenins - lendel), Qnil))); |
1133 combine_after_change_list | 1422 combine_after_change_list |
1134 = Fcons (elt, combine_after_change_list); | 1423 = Fcons (elt, combine_after_change_list); |
1135 combine_after_change_buffer = Fcurrent_buffer (); | 1424 combine_after_change_buffer = Fcurrent_buffer (); |
1136 | 1425 |
1143 /* Run the after-change-function if any. | 1432 /* Run the after-change-function if any. |
1144 We don't bother "binding" this variable to nil | 1433 We don't bother "binding" this variable to nil |
1145 because it is obsolete anyway and new code should not use it. */ | 1434 because it is obsolete anyway and new code should not use it. */ |
1146 if (!NILP (Vafter_change_function)) | 1435 if (!NILP (Vafter_change_function)) |
1147 call3 (Vafter_change_function, | 1436 call3 (Vafter_change_function, |
1148 make_number (pos), make_number (pos + lenins), | 1437 make_number (charpos), make_number (charpos + lenins), |
1149 make_number (lendel)); | 1438 make_number (lendel)); |
1150 | 1439 |
1151 if (!NILP (Vafter_change_functions)) | 1440 if (!NILP (Vafter_change_functions)) |
1152 { | 1441 { |
1153 Lisp_Object args[4]; | 1442 Lisp_Object args[4]; |
1164 Vafter_change_functions = Qnil; | 1453 Vafter_change_functions = Qnil; |
1165 GCPRO2 (before_change_functions, after_change_functions); | 1454 GCPRO2 (before_change_functions, after_change_functions); |
1166 | 1455 |
1167 /* Actually run the hook functions. */ | 1456 /* Actually run the hook functions. */ |
1168 args[0] = Qafter_change_functions; | 1457 args[0] = Qafter_change_functions; |
1169 XSETFASTINT (args[1], pos); | 1458 XSETFASTINT (args[1], charpos); |
1170 XSETFASTINT (args[2], pos + lenins); | 1459 XSETFASTINT (args[2], charpos + lenins); |
1171 XSETFASTINT (args[3], lendel); | 1460 XSETFASTINT (args[3], lendel); |
1172 run_hook_list_with_args (after_change_functions, | 1461 run_hook_list_with_args (after_change_functions, |
1173 4, args); | 1462 4, args); |
1174 | 1463 |
1175 /* "Unbind" the variables we "bound" to nil. */ | 1464 /* "Unbind" the variables we "bound" to nil. */ |
1178 UNGCPRO; | 1467 UNGCPRO; |
1179 } | 1468 } |
1180 | 1469 |
1181 if (!NILP (current_buffer->overlays_before) | 1470 if (!NILP (current_buffer->overlays_before) |
1182 || !NILP (current_buffer->overlays_after)) | 1471 || !NILP (current_buffer->overlays_after)) |
1183 report_overlay_modification (make_number (pos), | 1472 report_overlay_modification (make_number (charpos), |
1184 make_number (pos + lenins), | 1473 make_number (charpos + lenins), |
1185 1, | 1474 1, |
1186 make_number (pos), make_number (pos + lenins), | 1475 make_number (charpos), |
1476 make_number (charpos + lenins), | |
1187 make_number (lendel)); | 1477 make_number (lendel)); |
1188 | 1478 |
1189 /* After an insertion, call the text properties | 1479 /* After an insertion, call the text properties |
1190 insert-behind-hooks or insert-in-front-hooks. */ | 1480 insert-behind-hooks or insert-in-front-hooks. */ |
1191 if (lendel == 0) | 1481 if (lendel == 0) |
1192 report_interval_modification (pos, pos + lenins); | 1482 report_interval_modification (charpos, charpos + lenins); |
1193 } | 1483 } |
1194 | 1484 |
1195 Lisp_Object | 1485 Lisp_Object |
1196 Fcombine_after_change_execute_1 (val) | 1486 Fcombine_after_change_execute_1 (val) |
1197 Lisp_Object val; | 1487 Lisp_Object val; |