1 /* Buffer insertion/deletion and gap motion for GNU Emacs.
2 Copyright (C) 1985, 1986, 1993, 1994, 1995 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 2, or (at your option)
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. */
23 #include "intervals.h"
26 #include "blockinput.h"
28 #define min(x, y) ((x) < (y) ? (x) : (y))
30 static void insert_from_string_1 ();
31 static void insert_from_buffer_1 ();
32 static void gap_left ();
33 static void gap_right ();
34 static void adjust_markers ();
35 static void adjust_point ();
37 /* Move gap to position `pos'.
38 Note that this can quit! */
50 /* Move the gap to POS, which is less than the current GPT.
51 If NEWGAP is nonzero, then don't update beg_unchanged and end_unchanged. */
54 gap_left (pos
, newgap
)
58 register unsigned char *to
, *from
;
66 if (unchanged_modified
== MODIFF
)
69 end_unchanged
= Z
- pos
- 1;
73 if (Z
- GPT
< end_unchanged
)
74 end_unchanged
= Z
- GPT
;
75 if (pos
< beg_unchanged
)
85 /* Now copy the characters. To move the gap down,
86 copy characters up. */
90 /* I gets number of characters left to copy. */
94 /* If a quit is requested, stop copying now.
95 Change POS to be where we have actually moved the gap to. */
101 /* Move at most 32000 chars before checking again for a quit. */
106 /* bcopy is safe if the two areas of memory do not overlap
107 or on systems where bcopy is always safe for moving upward. */
108 && (BCOPY_UPWARD_SAFE
109 || to
- from
>= 128))
111 /* If overlap is not safe, avoid it by not moving too many
112 characters at once. */
113 if (!BCOPY_UPWARD_SAFE
&& i
> to
- from
)
128 /* Adjust markers, and buffer data structure, to put the gap at POS.
129 POS is where the loop above stopped, which may be what was specified
130 or may be where a quit was detected. */
131 adjust_markers (pos
+ 1, GPT
, GAP_SIZE
);
140 register unsigned char *to
, *from
;
146 if (unchanged_modified
== MODIFF
)
149 end_unchanged
= Z
- pos
- 1;
153 if (Z
- pos
- 1 < end_unchanged
)
154 end_unchanged
= Z
- pos
- 1;
155 if (GPT
- BEG
< beg_unchanged
)
156 beg_unchanged
= GPT
- BEG
;
164 /* Now copy the characters. To move the gap up,
165 copy characters down. */
169 /* I gets number of characters left to copy. */
173 /* If a quit is requested, stop copying now.
174 Change POS to be where we have actually moved the gap to. */
180 /* Move at most 32000 chars before checking again for a quit. */
185 /* bcopy is safe if the two areas of memory do not overlap
186 or on systems where bcopy is always safe for moving downward. */
187 && (BCOPY_DOWNWARD_SAFE
188 || from
- to
>= 128))
190 /* If overlap is not safe, avoid it by not moving too many
191 characters at once. */
192 if (!BCOPY_DOWNWARD_SAFE
&& i
> from
- to
)
207 adjust_markers (GPT
+ GAP_SIZE
, pos
+ 1 + GAP_SIZE
, - GAP_SIZE
);
212 /* Add `amount' to the position of every marker in the current buffer
213 whose current position is between `from' (exclusive) and `to' (inclusive).
214 Also, any markers past the outside of that interval, in the direction
215 of adjustment, are first moved back to the near end of the interval
216 and then adjusted by `amount'. */
219 adjust_markers (from
, to
, amount
)
220 register int from
, to
, amount
;
223 register struct Lisp_Marker
*m
;
226 marker
= BUF_MARKERS (current_buffer
);
228 while (!NILP (marker
))
230 m
= XMARKER (marker
);
234 if (mpos
> to
&& mpos
< to
+ amount
)
239 if (mpos
> from
+ amount
&& mpos
<= from
)
240 mpos
= from
+ amount
;
242 if (mpos
> from
&& mpos
<= to
)
249 /* Adjust markers whose insertion-type is t
250 for an insertion of AMOUNT characters at POS. */
253 adjust_markers_for_insert (pos
, amount
)
254 register int pos
, amount
;
258 marker
= BUF_MARKERS (current_buffer
);
260 while (!NILP (marker
))
262 register struct Lisp_Marker
*m
= XMARKER (marker
);
263 if (m
->insertion_type
&& m
->bufpos
== pos
)
269 /* Add the specified amount to point. This is used only when the value
270 of point changes due to an insert or delete; it does not represent
271 a conceptual change in point as a marker. In particular, point is
272 not crossing any interval boundaries, so there's no need to use the
273 usual SET_PT macro. In fact it would be incorrect to do so, because
274 either the old or the new value of point is out of synch with the
275 current set of intervals. */
277 adjust_point (amount
)
280 BUF_PT (current_buffer
) += amount
;
283 /* Make the gap INCREMENT characters longer. */
289 unsigned char *result
;
294 /* If we have to get more space, get enough to last a while. */
297 /* Don't allow a buffer size that won't fit in an int
298 even if it will fit in a Lisp integer.
299 That won't work because so many places use `int'. */
301 if (Z
- BEG
+ GAP_SIZE
+ increment
302 >= ((unsigned) 1 << (min (INTBITS
, VALBITS
) - 1)))
303 error ("Buffer exceeds maximum size");
306 result
= BUFFER_REALLOC (BEG_ADDR
, (Z
- BEG
+ GAP_SIZE
+ increment
));
314 /* We can't unblock until the new address is properly stored. */
318 /* Prevent quitting in move_gap. */
323 old_gap_size
= GAP_SIZE
;
325 /* Call the newly allocated space a gap at the end of the whole space. */
327 GAP_SIZE
= increment
;
329 /* Move the new gap down to be consecutive with the end of the old one.
330 This adjusts the markers properly too. */
331 gap_left (real_gap_loc
+ old_gap_size
, 1);
333 /* Now combine the two into one large gap. */
334 GAP_SIZE
+= old_gap_size
;
340 /* Insert a string of specified length before point.
341 DO NOT use this for the contents of a Lisp string or a Lisp buffer!
342 prepare_to_modify_buffer could relocate the text. */
345 insert (string
, length
)
346 register unsigned char *string
;
351 insert_1 (string
, length
, 0, 1);
352 signal_after_change (PT
-length
, 0, length
);
357 insert_and_inherit (string
, length
)
358 register unsigned char *string
;
363 insert_1 (string
, length
, 1, 1);
364 signal_after_change (PT
-length
, 0, length
);
369 insert_1 (string
, length
, inherit
, prepare
)
370 register unsigned char *string
;
372 int inherit
, prepare
;
374 register Lisp_Object temp
;
377 prepare_to_modify_buffer (PT
, PT
);
381 if (GAP_SIZE
< length
)
382 make_gap (length
- GAP_SIZE
);
384 record_insert (PT
, length
);
387 bcopy (string
, GPT_ADDR
, length
);
389 #ifdef USE_TEXT_PROPERTIES
390 if (BUF_INTERVALS (current_buffer
) != 0)
391 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
392 offset_intervals (current_buffer
, PT
, length
);
399 adjust_overlays_for_insert (PT
, length
);
400 adjust_markers_for_insert (PT
, length
);
401 adjust_point (length
);
403 #ifdef USE_TEXT_PROPERTIES
404 if (!inherit
&& BUF_INTERVALS (current_buffer
) != 0)
405 Fset_text_properties (make_number (PT
- length
), make_number (PT
),
410 /* Insert the part of the text of STRING, a Lisp object assumed to be
411 of type string, consisting of the LENGTH characters starting at
412 position POS. If the text of STRING has properties, they are absorbed
415 It does not work to use `insert' for this, because a GC could happen
416 before we bcopy the stuff into the buffer, and relocate the string
417 without insert noticing. */
420 insert_from_string (string
, pos
, length
, inherit
)
422 register int pos
, length
;
427 insert_from_string_1 (string
, pos
, length
, inherit
);
428 signal_after_change (PT
-length
, 0, length
);
433 insert_from_string_1 (string
, pos
, length
, inherit
)
435 register int pos
, length
;
438 register Lisp_Object temp
;
441 /* Make sure point-max won't overflow after this insertion. */
442 XSETINT (temp
, length
+ Z
);
443 if (length
+ Z
!= XINT (temp
))
444 error ("maximum buffer size exceeded");
447 prepare_to_modify_buffer (PT
, PT
);
451 if (GAP_SIZE
< length
)
452 make_gap (length
- GAP_SIZE
);
454 record_insert (PT
, length
);
458 bcopy (XSTRING (string
)->data
, GPT_ADDR
, length
);
460 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
461 offset_intervals (current_buffer
, PT
, length
);
467 adjust_overlays_for_insert (PT
, length
);
468 adjust_markers_for_insert (PT
, length
);
470 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
471 graft_intervals_into_buffer (XSTRING (string
)->intervals
, PT
, length
,
472 current_buffer
, inherit
);
474 adjust_point (length
);
477 /* Insert text from BUF, starting at POS and having length LENGTH, into the
478 current buffer. If the text in BUF has properties, they are absorbed
479 into the current buffer.
481 It does not work to use `insert' for this, because a malloc could happen
482 and relocate BUF's text before the bcopy happens. */
485 insert_from_buffer (buf
, pos
, length
, inherit
)
492 insert_from_buffer_1 (buf
, pos
, length
, inherit
);
493 signal_after_change (PT
-length
, 0, length
);
498 insert_from_buffer_1 (buf
, pos
, length
, inherit
)
503 register Lisp_Object temp
;
506 /* Make sure point-max won't overflow after this insertion. */
507 XSETINT (temp
, length
+ Z
);
508 if (length
+ Z
!= XINT (temp
))
509 error ("maximum buffer size exceeded");
511 prepare_to_modify_buffer (PT
, PT
);
515 if (GAP_SIZE
< length
)
516 make_gap (length
- GAP_SIZE
);
518 record_insert (PT
, length
);
521 if (pos
< BUF_GPT (buf
))
523 chunk
= BUF_GPT (buf
) - pos
;
526 bcopy (BUF_CHAR_ADDRESS (buf
, pos
), GPT_ADDR
, chunk
);
531 bcopy (BUF_CHAR_ADDRESS (buf
, pos
+ chunk
),
532 GPT_ADDR
+ chunk
, length
- chunk
);
534 #ifdef USE_TEXT_PROPERTIES
535 if (BUF_INTERVALS (current_buffer
) != 0)
536 offset_intervals (current_buffer
, PT
, length
);
543 adjust_overlays_for_insert (PT
, length
);
544 adjust_markers_for_insert (PT
, length
);
545 adjust_point (length
);
547 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
548 graft_intervals_into_buffer (copy_intervals (BUF_INTERVALS (buf
),
550 PT
- length
, length
, current_buffer
, inherit
);
553 /* Insert the character C before point */
562 /* Insert the null-terminated string S before point */
568 insert (s
, strlen (s
));
571 /* Like `insert' except that all markers pointing at the place where
572 the insertion happens are adjusted to point after it.
573 Don't use this function to insert part of a Lisp string,
574 since gc could happen and relocate it. */
577 insert_before_markers (string
, length
)
578 unsigned char *string
;
583 register int opoint
= PT
;
584 insert_1 (string
, length
, 0, 1);
585 adjust_markers (opoint
- 1, opoint
, length
);
586 signal_after_change (PT
-length
, 0, length
);
591 insert_before_markers_and_inherit (string
, length
)
592 unsigned char *string
;
597 register int opoint
= PT
;
598 insert_1 (string
, length
, 1, 1);
599 adjust_markers (opoint
- 1, opoint
, length
);
600 signal_after_change (PT
-length
, 0, length
);
604 /* Insert part of a Lisp string, relocating markers after. */
607 insert_from_string_before_markers (string
, pos
, length
, inherit
)
609 register int pos
, length
;
614 register int opoint
= PT
;
615 insert_from_string_1 (string
, pos
, length
, inherit
);
616 adjust_markers (opoint
- 1, opoint
, length
);
617 signal_after_change (PT
-length
, 0, length
);
621 /* Delete characters in current buffer
622 from FROM up to (but not including) TO. */
626 register int from
, to
;
628 del_range_1 (from
, to
, 1);
631 /* Like del_range; PREPARE says whether to call prepare_to_modify_buffer. */
634 del_range_1 (from
, to
, prepare
)
635 register int from
, to
, prepare
;
639 /* Make args be valid */
645 if ((numdel
= to
- from
) <= 0)
648 /* Make sure the gap is somewhere in or next to what we are deleting. */
655 prepare_to_modify_buffer (from
, to
);
657 record_delete (from
, numdel
);
660 /* Relocate point as if it were a marker. */
662 adjust_point (from
- (PT
< to
? PT
: to
));
664 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
665 offset_intervals (current_buffer
, from
, - numdel
);
667 /* Relocate all markers pointing into the new, larger gap
668 to point at the end of the text before the gap. */
669 adjust_markers (to
+ GAP_SIZE
, to
+ GAP_SIZE
, - numdel
- GAP_SIZE
);
671 /* Adjust the overlay center as needed. This must be done after
672 adjusting the markers that bound the overlays. */
673 adjust_overlays_for_delete (from
, numdel
);
680 if (GPT
- BEG
< beg_unchanged
)
681 beg_unchanged
= GPT
- BEG
;
682 if (Z
- GPT
< end_unchanged
)
683 end_unchanged
= Z
- GPT
;
685 evaporate_overlays (from
);
686 signal_after_change (from
, numdel
, 0);
689 /* Call this if you're about to change the region of BUFFER from START
690 to END. This checks the read-only properties of the region, calls
691 the necessary modification hooks, and warns the next redisplay that
692 it should pay attention to that area. */
694 modify_region (buffer
, start
, end
)
695 struct buffer
*buffer
;
698 struct buffer
*old_buffer
= current_buffer
;
700 if (buffer
!= old_buffer
)
701 set_buffer_internal (buffer
);
703 prepare_to_modify_buffer (start
, end
);
705 if (start
- 1 < beg_unchanged
|| unchanged_modified
== MODIFF
)
706 beg_unchanged
= start
- 1;
707 if (Z
- end
< end_unchanged
708 || unchanged_modified
== MODIFF
)
709 end_unchanged
= Z
- end
;
711 if (MODIFF
<= SAVE_MODIFF
)
712 record_first_change ();
715 buffer
->point_before_scroll
= Qnil
;
717 if (buffer
!= old_buffer
)
718 set_buffer_internal (old_buffer
);
721 /* Check that it is okay to modify the buffer between START and END.
722 Run the before-change-function, if any. If intervals are in use,
723 verify that the text to be modified is not read-only, and call
724 any modification properties the text may have. */
727 prepare_to_modify_buffer (start
, end
)
728 Lisp_Object start
, end
;
730 if (!NILP (current_buffer
->read_only
))
731 Fbarf_if_buffer_read_only ();
733 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
734 if (BUF_INTERVALS (current_buffer
) != 0)
735 verify_interval_modification (current_buffer
, start
, end
);
737 #ifdef CLASH_DETECTION
738 if (!NILP (current_buffer
->file_truename
)
739 /* Make binding buffer-file-name to nil effective. */
740 && !NILP (current_buffer
->filename
)
741 && SAVE_MODIFF
>= MODIFF
)
742 lock_file (current_buffer
->file_truename
);
744 /* At least warn if this file has changed on disk since it was visited. */
745 if (!NILP (current_buffer
->filename
)
746 && SAVE_MODIFF
>= MODIFF
747 && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
748 && !NILP (Ffile_exists_p (current_buffer
->filename
)))
749 call1 (intern ("ask-user-about-supersession-threat"),
750 current_buffer
->filename
);
751 #endif /* not CLASH_DETECTION */
753 signal_before_change (start
, end
);
755 if (current_buffer
->newline_cache
)
756 invalidate_region_cache (current_buffer
,
757 current_buffer
->newline_cache
,
758 start
- BEG
, Z
- end
);
759 if (current_buffer
->width_run_cache
)
760 invalidate_region_cache (current_buffer
,
761 current_buffer
->width_run_cache
,
762 start
- BEG
, Z
- end
);
764 Vdeactivate_mark
= Qt
;
767 /* Signal a change to the buffer immediately before it happens.
768 START and END are the bounds of the text to be changed,
772 signal_before_change (start
, end
)
773 Lisp_Object start
, end
;
775 /* If buffer is unmodified, run a special hook for that case. */
776 if (SAVE_MODIFF
>= MODIFF
777 && !NILP (Vfirst_change_hook
)
778 && !NILP (Vrun_hooks
))
779 call1 (Vrun_hooks
, Qfirst_change_hook
);
781 /* Run the before-change-function if any.
782 We don't bother "binding" this variable to nil
783 because it is obsolete anyway and new code should not use it. */
784 if (!NILP (Vbefore_change_function
))
785 call2 (Vbefore_change_function
, start
, end
);
787 /* Now run the before-change-functions if any. */
788 if (!NILP (Vbefore_change_functions
))
791 Lisp_Object before_change_functions
;
792 Lisp_Object after_change_functions
;
793 struct gcpro gcpro1
, gcpro2
;
795 /* "Bind" before-change-functions and after-change-functions
796 to nil--but in a way that errors don't know about.
797 That way, if there's an error in them, they will stay nil. */
798 before_change_functions
= Vbefore_change_functions
;
799 after_change_functions
= Vafter_change_functions
;
800 Vbefore_change_functions
= Qnil
;
801 Vafter_change_functions
= Qnil
;
802 GCPRO2 (before_change_functions
, after_change_functions
);
804 /* Actually run the hook functions. */
805 args
[0] = Qbefore_change_functions
;
808 run_hook_list_with_args (before_change_functions
, 3, args
);
810 /* "Unbind" the variables we "bound" to nil. */
811 Vbefore_change_functions
= before_change_functions
;
812 Vafter_change_functions
= after_change_functions
;
816 if (!NILP (current_buffer
->overlays_before
)
817 || !NILP (current_buffer
->overlays_after
))
818 report_overlay_modification (start
, end
, 0, start
, end
, Qnil
);
821 /* Signal a change immediately after it happens.
822 POS is the address of the start of the changed text.
823 LENDEL is the number of characters of the text before the change.
824 (Not the whole buffer; just the part that was changed.)
825 LENINS is the number of characters in the changed text.
827 (Hence POS + LENINS - LENDEL is the position after the changed text.) */
830 signal_after_change (pos
, lendel
, lenins
)
831 int pos
, lendel
, lenins
;
833 /* Run the after-change-function if any.
834 We don't bother "binding" this variable to nil
835 because it is obsolete anyway and new code should not use it. */
836 if (!NILP (Vafter_change_function
))
837 call3 (Vafter_change_function
,
838 make_number (pos
), make_number (pos
+ lenins
),
839 make_number (lendel
));
841 if (!NILP (Vafter_change_functions
))
844 Lisp_Object before_change_functions
;
845 Lisp_Object after_change_functions
;
846 struct gcpro gcpro1
, gcpro2
;
848 /* "Bind" before-change-functions and after-change-functions
849 to nil--but in a way that errors don't know about.
850 That way, if there's an error in them, they will stay nil. */
851 before_change_functions
= Vbefore_change_functions
;
852 after_change_functions
= Vafter_change_functions
;
853 Vbefore_change_functions
= Qnil
;
854 Vafter_change_functions
= Qnil
;
855 GCPRO2 (before_change_functions
, after_change_functions
);
857 /* Actually run the hook functions. */
858 args
[0] = Qafter_change_functions
;
859 XSETFASTINT (args
[1], pos
);
860 XSETFASTINT (args
[2], pos
+ lenins
);
861 XSETFASTINT (args
[3], lendel
);
862 run_hook_list_with_args (after_change_functions
,
865 /* "Unbind" the variables we "bound" to nil. */
866 Vbefore_change_functions
= before_change_functions
;
867 Vafter_change_functions
= after_change_functions
;
871 if (!NILP (current_buffer
->overlays_before
)
872 || !NILP (current_buffer
->overlays_after
))
873 report_overlay_modification (make_number (pos
),
874 make_number (pos
+ lenins
- lendel
),
876 make_number (pos
), make_number (pos
+ lenins
),
877 make_number (lendel
));
879 /* After an insertion, call the text properties
880 insert-behind-hooks or insert-in-front-hooks. */
882 report_interval_modification (pos
, pos
+ lenins
);