doc fix.
[emacs.git] / src / insdel.c
blob5cee99f89cd8c299edaf71162329a96ae2a6157a
1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 1986, 1993, 1994 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
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
8 the Free Software Foundation; either version 1, or (at your option)
9 any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 #include <config.h>
22 #include "lisp.h"
23 #include "intervals.h"
24 #include "buffer.h"
25 #include "window.h"
26 #include "blockinput.h"
28 static void insert_1 ();
29 static void insert_from_string_1 ();
31 /* Move gap to position `pos'.
32 Note that this can quit! */
34 move_gap (pos)
35 int pos;
37 if (pos < GPT)
38 gap_left (pos, 0);
39 else if (pos > GPT)
40 gap_right (pos);
43 /* Move the gap to POS, which is less than the current GPT.
44 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
46 gap_left (pos, newgap)
47 register int pos;
48 int newgap;
50 register unsigned char *to, *from;
51 register int i;
52 int new_s1;
54 pos--;
56 if (!newgap)
58 if (unchanged_modified == MODIFF)
60 beg_unchanged = pos;
61 end_unchanged = Z - pos - 1;
63 else
65 if (Z - GPT < end_unchanged)
66 end_unchanged = Z - GPT;
67 if (pos < beg_unchanged)
68 beg_unchanged = pos;
72 i = GPT;
73 to = GAP_END_ADDR;
74 from = GPT_ADDR;
75 new_s1 = GPT - BEG;
77 /* Now copy the characters. To move the gap down,
78 copy characters up. */
80 while (1)
82 /* I gets number of characters left to copy. */
83 i = new_s1 - pos;
84 if (i == 0)
85 break;
86 /* If a quit is requested, stop copying now.
87 Change POS to be where we have actually moved the gap to. */
88 if (QUITP)
90 pos = new_s1;
91 break;
93 /* Move at most 32000 chars before checking again for a quit. */
94 if (i > 32000)
95 i = 32000;
96 #ifdef GAP_USE_BCOPY
97 if (i >= 128
98 /* bcopy is safe if the two areas of memory do not overlap
99 or on systems where bcopy is always safe for moving upward. */
100 && (BCOPY_UPWARD_SAFE
101 || to - from >= 128))
103 /* If overlap is not safe, avoid it by not moving too many
104 characters at once. */
105 if (!BCOPY_UPWARD_SAFE && i > to - from)
106 i = to - from;
107 new_s1 -= i;
108 from -= i, to -= i;
109 bcopy (from, to, i);
111 else
112 #endif
114 new_s1 -= i;
115 while (--i >= 0)
116 *--to = *--from;
120 /* Adjust markers, and buffer data structure, to put the gap at POS.
121 POS is where the loop above stopped, which may be what was specified
122 or may be where a quit was detected. */
123 adjust_markers (pos + 1, GPT, GAP_SIZE);
124 GPT = pos + 1;
125 QUIT;
128 gap_right (pos)
129 register int pos;
131 register unsigned char *to, *from;
132 register int i;
133 int new_s1;
135 pos--;
137 if (unchanged_modified == MODIFF)
139 beg_unchanged = pos;
140 end_unchanged = Z - pos - 1;
142 else
144 if (Z - pos - 1 < end_unchanged)
145 end_unchanged = Z - pos - 1;
146 if (GPT - BEG < beg_unchanged)
147 beg_unchanged = GPT - BEG;
150 i = GPT;
151 from = GAP_END_ADDR;
152 to = GPT_ADDR;
153 new_s1 = GPT - 1;
155 /* Now copy the characters. To move the gap up,
156 copy characters down. */
158 while (1)
160 /* I gets number of characters left to copy. */
161 i = pos - new_s1;
162 if (i == 0)
163 break;
164 /* If a quit is requested, stop copying now.
165 Change POS to be where we have actually moved the gap to. */
166 if (QUITP)
168 pos = new_s1;
169 break;
171 /* Move at most 32000 chars before checking again for a quit. */
172 if (i > 32000)
173 i = 32000;
174 #ifdef GAP_USE_BCOPY
175 if (i >= 128
176 /* bcopy is safe if the two areas of memory do not overlap
177 or on systems where bcopy is always safe for moving downward. */
178 && (BCOPY_DOWNWARD_SAFE
179 || from - to >= 128))
181 /* If overlap is not safe, avoid it by not moving too many
182 characters at once. */
183 if (!BCOPY_DOWNWARD_SAFE && i > from - to)
184 i = from - to;
185 new_s1 += i;
186 bcopy (from, to, i);
187 from += i, to += i;
189 else
190 #endif
192 new_s1 += i;
193 while (--i >= 0)
194 *to++ = *from++;
198 adjust_markers (GPT + GAP_SIZE, pos + 1 + GAP_SIZE, - GAP_SIZE);
199 GPT = pos + 1;
200 QUIT;
203 /* Add `amount' to the position of every marker in the current buffer
204 whose current position is between `from' (exclusive) and `to' (inclusive).
205 Also, any markers past the outside of that interval, in the direction
206 of adjustment, are first moved back to the near end of the interval
207 and then adjusted by `amount'. */
209 adjust_markers (from, to, amount)
210 register int from, to, amount;
212 Lisp_Object marker;
213 register struct Lisp_Marker *m;
214 register int mpos;
216 marker = current_buffer->markers;
218 while (!NILP (marker))
220 m = XMARKER (marker);
221 mpos = m->bufpos;
222 if (amount > 0)
224 if (mpos > to && mpos < to + amount)
225 mpos = to + amount;
227 else
229 if (mpos > from + amount && mpos <= from)
230 mpos = from + amount;
232 if (mpos > from && mpos <= to)
233 mpos += amount;
234 m->bufpos = mpos;
235 marker = m->chain;
239 /* Make the gap INCREMENT characters longer. */
241 make_gap (increment)
242 int increment;
244 unsigned char *result;
245 Lisp_Object tem;
246 int real_gap_loc;
247 int old_gap_size;
249 /* If we have to get more space, get enough to last a while. */
250 increment += 2000;
252 BLOCK_INPUT;
253 result = BUFFER_REALLOC (BEG_ADDR, (Z - BEG + GAP_SIZE + increment));
254 UNBLOCK_INPUT;
256 if (result == 0)
257 memory_full ();
258 BEG_ADDR = result;
260 /* Prevent quitting in move_gap. */
261 tem = Vinhibit_quit;
262 Vinhibit_quit = Qt;
264 real_gap_loc = GPT;
265 old_gap_size = GAP_SIZE;
267 /* Call the newly allocated space a gap at the end of the whole space. */
268 GPT = Z + GAP_SIZE;
269 GAP_SIZE = increment;
271 /* Move the new gap down to be consecutive with the end of the old one.
272 This adjusts the markers properly too. */
273 gap_left (real_gap_loc + old_gap_size, 1);
275 /* Now combine the two into one large gap. */
276 GAP_SIZE += old_gap_size;
277 GPT = real_gap_loc;
279 Vinhibit_quit = tem;
282 /* Insert a string of specified length before point.
283 DO NOT use this for the contents of a Lisp string!
284 prepare_to_modify_buffer could relocate the string. */
286 insert (string, length)
287 register unsigned char *string;
288 register length;
290 if (length > 0)
292 insert_1 (string, length);
293 signal_after_change (point-length, 0, length);
297 static void
298 insert_1 (string, length)
299 register unsigned char *string;
300 register length;
302 register Lisp_Object temp;
304 /* Make sure point-max won't overflow after this insertion. */
305 XSET (temp, Lisp_Int, length + Z);
306 if (length + Z != XINT (temp))
307 error ("maximum buffer size exceeded");
309 prepare_to_modify_buffer (point, point);
311 if (point != GPT)
312 move_gap (point);
313 if (GAP_SIZE < length)
314 make_gap (length - GAP_SIZE);
316 record_insert (point, length);
317 MODIFF++;
319 bcopy (string, GPT_ADDR, length);
321 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
322 offset_intervals (current_buffer, point, length);
324 GAP_SIZE -= length;
325 GPT += length;
326 ZV += length;
327 Z += length;
328 SET_PT (point + length);
331 /* Insert the part of the text of STRING, a Lisp object assumed to be
332 of type string, consisting of the LENGTH characters starting at
333 position POS. If the text of STRING has properties, they are absorbed
334 into the buffer.
336 It does not work to use `insert' for this, because a GC could happen
337 before we bcopy the stuff into the buffer, and relocate the string
338 without insert noticing. */
340 insert_from_string (string, pos, length, inherit)
341 Lisp_Object string;
342 register int pos, length;
343 int inherit;
345 if (length > 0)
347 insert_from_string_1 (string, pos, length, inherit);
348 signal_after_change (point-length, 0, length);
352 static void
353 insert_from_string_1 (string, pos, length, inherit)
354 Lisp_Object string;
355 register int pos, length;
356 int inherit;
358 register Lisp_Object temp;
359 struct gcpro gcpro1;
361 /* Make sure point-max won't overflow after this insertion. */
362 XSET (temp, Lisp_Int, length + Z);
363 if (length + Z != XINT (temp))
364 error ("maximum buffer size exceeded");
366 GCPRO1 (string);
367 prepare_to_modify_buffer (point, point);
369 if (point != GPT)
370 move_gap (point);
371 if (GAP_SIZE < length)
372 make_gap (length - GAP_SIZE);
374 record_insert (point, length);
375 MODIFF++;
376 UNGCPRO;
378 bcopy (XSTRING (string)->data, GPT_ADDR, length);
380 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
381 offset_intervals (current_buffer, point, length);
383 GAP_SIZE -= length;
384 GPT += length;
385 ZV += length;
386 Z += length;
388 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
389 graft_intervals_into_buffer (XSTRING (string)->intervals, point, length,
390 current_buffer, inherit);
392 SET_PT (point + length);
395 /* Insert the character C before point */
397 void
398 insert_char (c)
399 unsigned char c;
401 insert (&c, 1);
404 /* Insert the null-terminated string S before point */
406 void
407 insert_string (s)
408 char *s;
410 insert (s, strlen (s));
413 /* Like `insert' except that all markers pointing at the place where
414 the insertion happens are adjusted to point after it.
415 Don't use this function to insert part of a Lisp string,
416 since gc could happen and relocate it. */
418 insert_before_markers (string, length)
419 unsigned char *string;
420 register int length;
422 if (length > 0)
424 register int opoint = point;
425 insert_1 (string, length);
426 adjust_markers (opoint - 1, opoint, length);
427 signal_after_change (point-length, 0, length);
431 /* Insert part of a Lisp string, relocating markers after. */
433 insert_from_string_before_markers (string, pos, length, inherit)
434 Lisp_Object string;
435 register int pos, length;
436 int inherit;
438 if (length > 0)
440 register int opoint = point;
441 insert_from_string_1 (string, pos, length, inherit);
442 adjust_markers (opoint - 1, opoint, length);
443 signal_after_change (point-length, 0, length);
447 /* Delete characters in current buffer
448 from FROM up to (but not including) TO. */
450 del_range (from, to)
451 register int from, to;
453 return del_range_1 (from, to, 1);
456 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
458 del_range_1 (from, to, prepare)
459 register int from, to, prepare;
461 register int numdel;
463 /* Make args be valid */
464 if (from < BEGV)
465 from = BEGV;
466 if (to > ZV)
467 to = ZV;
469 if ((numdel = to - from) <= 0)
470 return;
472 /* Make sure the gap is somewhere in or next to what we are deleting. */
473 if (from > GPT)
474 gap_right (from);
475 if (to < GPT)
476 gap_left (to, 0);
478 if (prepare)
479 prepare_to_modify_buffer (from, to);
481 record_delete (from, numdel);
482 MODIFF++;
484 /* Relocate point as if it were a marker. */
485 if (from < point)
487 if (point < to)
488 SET_PT (from);
489 else
490 SET_PT (point - numdel);
493 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
494 offset_intervals (current_buffer, from, - numdel);
496 /* Relocate all markers pointing into the new, larger gap
497 to point at the end of the text before the gap. */
498 adjust_markers (to + GAP_SIZE, to + GAP_SIZE, - numdel - GAP_SIZE);
500 GAP_SIZE += numdel;
501 ZV -= numdel;
502 Z -= numdel;
503 GPT = from;
505 if (GPT - BEG < beg_unchanged)
506 beg_unchanged = GPT - BEG;
507 if (Z - GPT < end_unchanged)
508 end_unchanged = Z - GPT;
510 signal_after_change (from, numdel, 0);
513 /* Call this if you're about to change the region of BUFFER from START
514 to END. This checks the read-only properties of the region, calls
515 the necessary modification hooks, and warns the next redisplay that
516 it should pay attention to that area. */
517 modify_region (buffer, start, end)
518 struct buffer *buffer;
519 int start, end;
521 struct buffer *old_buffer = current_buffer;
523 if (buffer != old_buffer)
524 set_buffer_internal (buffer);
526 prepare_to_modify_buffer (start, end);
528 if (start - 1 < beg_unchanged || unchanged_modified == MODIFF)
529 beg_unchanged = start - 1;
530 if (Z - end < end_unchanged
531 || unchanged_modified == MODIFF)
532 end_unchanged = Z - end;
534 if (MODIFF <= current_buffer->save_modified)
535 record_first_change ();
536 MODIFF++;
538 if (buffer != old_buffer)
539 set_buffer_internal (old_buffer);
542 /* Check that it is okay to modify the buffer between START and END.
543 Run the before-change-function, if any. If intervals are in use,
544 verify that the text to be modified is not read-only, and call
545 any modification properties the text may have. */
547 prepare_to_modify_buffer (start, end)
548 Lisp_Object start, end;
550 if (!NILP (current_buffer->read_only))
551 Fbarf_if_buffer_read_only ();
553 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
554 verify_interval_modification (current_buffer, start, end);
556 verify_overlay_modification (start, end);
558 #ifdef CLASH_DETECTION
559 if (!NILP (current_buffer->filename)
560 && current_buffer->save_modified >= MODIFF)
561 lock_file (current_buffer->filename);
562 #else
563 /* At least warn if this file has changed on disk since it was visited. */
564 if (!NILP (current_buffer->filename)
565 && current_buffer->save_modified >= MODIFF
566 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
567 && !NILP (Ffile_exists_p (current_buffer->filename)))
568 call1 (intern ("ask-user-about-supersession-threat"),
569 current_buffer->filename);
570 #endif /* not CLASH_DETECTION */
572 signal_before_change (start, end);
574 Vdeactivate_mark = Qt;
577 static Lisp_Object
578 before_change_function_restore (value)
579 Lisp_Object value;
581 Vbefore_change_function = value;
584 static Lisp_Object
585 after_change_function_restore (value)
586 Lisp_Object value;
588 Vafter_change_function = value;
591 static Lisp_Object
592 before_change_functions_restore (value)
593 Lisp_Object value;
595 Vbefore_change_functions = value;
598 static Lisp_Object
599 after_change_functions_restore (value)
600 Lisp_Object value;
602 Vafter_change_functions = value;
605 /* Signal a change to the buffer immediately before it happens.
606 START and END are the bounds of the text to be changed,
607 as Lisp objects. */
609 signal_before_change (start, end)
610 Lisp_Object start, end;
612 /* If buffer is unmodified, run a special hook for that case. */
613 if (current_buffer->save_modified >= MODIFF
614 && !NILP (Vfirst_change_hook)
615 && !NILP (Vrun_hooks))
616 call1 (Vrun_hooks, Qfirst_change_hook);
618 /* Now in any case run the before-change-function if any. */
619 if (!NILP (Vbefore_change_function))
621 int count = specpdl_ptr - specpdl;
622 Lisp_Object function;
624 function = Vbefore_change_function;
626 record_unwind_protect (after_change_function_restore,
627 Vafter_change_function);
628 record_unwind_protect (before_change_function_restore,
629 Vbefore_change_function);
630 record_unwind_protect (after_change_functions_restore,
631 Vafter_change_functions);
632 record_unwind_protect (before_change_functions_restore,
633 Vbefore_change_functions);
634 Vafter_change_function = Qnil;
635 Vbefore_change_function = Qnil;
636 Vafter_change_functions = Qnil;
637 Vbefore_change_functions = Qnil;
639 call2 (function, start, end);
640 unbind_to (count, Qnil);
643 /* Now in any case run the before-change-function if any. */
644 if (!NILP (Vbefore_change_functions))
646 int count = specpdl_ptr - specpdl;
647 Lisp_Object functions;
649 functions = Vbefore_change_functions;
651 record_unwind_protect (after_change_function_restore,
652 Vafter_change_function);
653 record_unwind_protect (before_change_function_restore,
654 Vbefore_change_function);
655 record_unwind_protect (after_change_functions_restore,
656 Vafter_change_functions);
657 record_unwind_protect (before_change_functions_restore,
658 Vbefore_change_functions);
659 Vafter_change_function = Qnil;
660 Vbefore_change_function = Qnil;
661 Vafter_change_functions = Qnil;
662 Vbefore_change_functions = Qnil;
664 while (CONSP (functions))
666 call2 (XCONS (functions)->car, start, end);
667 functions = XCONS (functions)->cdr;
669 unbind_to (count, Qnil);
673 /* Signal a change immediately after it happens.
674 POS is the address of the start of the changed text.
675 LENDEL is the number of characters of the text before the change.
676 (Not the whole buffer; just the part that was changed.)
677 LENINS is the number of characters in the changed text. */
679 signal_after_change (pos, lendel, lenins)
680 int pos, lendel, lenins;
682 if (!NILP (Vafter_change_function))
684 int count = specpdl_ptr - specpdl;
685 Lisp_Object function;
686 function = Vafter_change_function;
688 record_unwind_protect (after_change_function_restore,
689 Vafter_change_function);
690 record_unwind_protect (before_change_function_restore,
691 Vbefore_change_function);
692 record_unwind_protect (after_change_functions_restore,
693 Vafter_change_functions);
694 record_unwind_protect (before_change_functions_restore,
695 Vbefore_change_functions);
696 Vafter_change_function = Qnil;
697 Vbefore_change_function = Qnil;
698 Vafter_change_functions = Qnil;
699 Vbefore_change_functions = Qnil;
701 call3 (function, make_number (pos), make_number (pos + lenins),
702 make_number (lendel));
703 unbind_to (count, Qnil);
705 if (!NILP (Vafter_change_functions))
707 int count = specpdl_ptr - specpdl;
708 Lisp_Object functions;
709 functions = Vafter_change_functions;
711 record_unwind_protect (after_change_function_restore,
712 Vafter_change_function);
713 record_unwind_protect (before_change_function_restore,
714 Vbefore_change_function);
715 record_unwind_protect (after_change_functions_restore,
716 Vafter_change_functions);
717 record_unwind_protect (before_change_functions_restore,
718 Vbefore_change_functions);
719 Vafter_change_function = Qnil;
720 Vbefore_change_function = Qnil;
721 Vafter_change_functions = Qnil;
722 Vbefore_change_functions = Qnil;
724 while (CONSP (functions))
726 call3 (XCONS (functions)->car,
727 make_number (pos), make_number (pos + lenins),
728 make_number (lendel));
729 functions = XCONS (functions)->cdr;
731 unbind_to (count, Qnil);