aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1996-11-09 21:36:00 +0000
committerRichard M. Stallman1996-11-09 21:36:00 +0000
commitfb2e7d144a3b441fee3b822ad4cf80c20102973b (patch)
treefa0f4d8c0b2e12fa75268fa7ac6676cccb45f35a /src
parent6aac2ab02e693eaa200d9ae1b717fe4eb9930048 (diff)
downloademacs-fb2e7d144a3b441fee3b822ad4cf80c20102973b.tar.gz
emacs-fb2e7d144a3b441fee3b822ad4cf80c20102973b.zip
(signal_after_change): If Vcombine_after_change_calls,
save up changes in combine_after_change_list. (Fcombine_after_change_execute) (Fcombine_after_change_execute_1): New subroutines. (syms_of_insdel): New function.
Diffstat (limited to 'src')
-rw-r--r--src/insdel.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/insdel.c b/src/insdel.c
index 872858041eb..b3bc81467fd 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -35,6 +35,27 @@ static void gap_right ();
35static void adjust_markers (); 35static void adjust_markers ();
36static void adjust_point (); 36static void adjust_point ();
37 37
38Lisp_Object Fcombine_after_change_execute ();
39
40/* Non-nil means don't call the after-change-functions right away,
41 just record an element in Vcombine_after_change_calls_list. */
42Lisp_Object Vcombine_after_change_calls;
43
44/* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
45 describing changes which happened while combine_after_change_calls
46 was nonzero. We use this to decide how to call them
47 once the deferral ends.
48
49 In each element.
50 BEG-UNCHANGED is the number of chars before the changed range.
51 END-UNCHANGED is the number of chars after the changed range,
52 and CHANGE-AMOUNT is the number of characters inserted by the change
53 (negative for a deletion). */
54Lisp_Object combine_after_change_list;
55
56/* Buffer which combine_after_change_list is about. */
57Lisp_Object combine_after_change_buffer;
58
38/* Move gap to position `pos'. 59/* Move gap to position `pos'.
39 Note that this can quit! */ 60 Note that this can quit! */
40 61
@@ -853,6 +874,33 @@ void
853signal_after_change (pos, lendel, lenins) 874signal_after_change (pos, lendel, lenins)
854 int pos, lendel, lenins; 875 int pos, lendel, lenins;
855{ 876{
877 /* If we are deferring calls to the after-change functions
878 and there are no before-change functions,
879 just record the args that we were going to use. */
880 if (! NILP (Vcombine_after_change_calls)
881 && NILP (Vbefore_change_function) && NILP (Vbefore_change_functions)
882 && NILP (current_buffer->overlays_before)
883 && NILP (current_buffer->overlays_after))
884 {
885 Lisp_Object elt;
886
887 if (!NILP (combine_after_change_list)
888 && current_buffer != XBUFFER (combine_after_change_buffer))
889 Fcombine_after_change_execute ();
890
891 elt = Fcons (make_number (pos - BEG),
892 Fcons (make_number (Z - (pos - lendel + lenins)),
893 Fcons (make_number (lenins - lendel), Qnil)));
894 combine_after_change_list
895 = Fcons (elt, combine_after_change_list);
896 combine_after_change_buffer = Fcurrent_buffer ();
897
898 return;
899 }
900
901 if (!NILP (combine_after_change_list))
902 Fcombine_after_change_execute ();
903
856 /* Run the after-change-function if any. 904 /* Run the after-change-function if any.
857 We don't bother "binding" this variable to nil 905 We don't bother "binding" this variable to nil
858 because it is obsolete anyway and new code should not use it. */ 906 because it is obsolete anyway and new code should not use it. */
@@ -904,3 +952,93 @@ signal_after_change (pos, lendel, lenins)
904 if (lendel == 0) 952 if (lendel == 0)
905 report_interval_modification (pos, pos + lenins); 953 report_interval_modification (pos, pos + lenins);
906} 954}
955
956Lisp_Object
957Fcombine_after_change_execute_1 (val)
958 Lisp_Object val;
959{
960 Vcombine_after_change_calls = val;
961 return val;
962}
963
964DEFUN ("combine-after-change-execute", Fcombine_after_change_execute,
965 Scombine_after_change_execute, 0, 0, 0,
966 "This function is for use internally in `combine-after-change-calls'.")
967 ()
968{
969 register Lisp_Object val;
970 int count = specpdl_ptr - specpdl;
971 int beg, end, change;
972 int begpos, endpos;
973 Lisp_Object tail;
974
975 record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
976
977 Fset_buffer (combine_after_change_buffer);
978
979 /* # chars unchanged at beginning of buffer. */
980 beg = Z - BEG;
981 /* # chars unchanged at end of buffer. */
982 end = beg;
983 /* Total amount of insertion (negative for deletion). */
984 change = 0;
985
986 /* Scan the various individual changes,
987 accumulating the range info in BEG, END and CHANGE. */
988 for (tail = combine_after_change_list; CONSP (tail);
989 tail = XCONS (tail)->cdr)
990 {
991 Lisp_Object elt, thisbeg, thisend, thischange;
992
993 /* Extract the info from the next element. */
994 elt = XCONS (tail)->car;
995 if (! CONSP (elt))
996 continue;
997 thisbeg = XINT (XCONS (elt)->car);
998
999 elt = XCONS (elt)->cdr;
1000 if (! CONSP (elt))
1001 continue;
1002 thisend = XINT (XCONS (elt)->car);
1003
1004 elt = XCONS (elt)->cdr;
1005 if (! CONSP (elt))
1006 continue;
1007 thischange = XINT (XCONS (elt)->car);
1008
1009 /* Merge this range into the accumulated range. */
1010 change += thischange;
1011 if (thisbeg < beg)
1012 beg = thisbeg;
1013 if (thisend < end)
1014 end = thisend;
1015 }
1016
1017 /* Get the current start and end positions of the range
1018 that was changed. */
1019 begpos = BEG + beg;
1020 endpos = Z - end;
1021
1022 /* We are about to handle these, so discard them. */
1023 combine_after_change_list = Qnil;
1024
1025 /* Now run the after-change functions for real.
1026 Turn off the flag that defers them. */
1027 record_unwind_protect (Fcombine_after_change_execute_1,
1028 Vcombine_after_change_calls);
1029 signal_after_change (begpos, endpos - begpos - change, endpos - begpos);
1030
1031 return unbind_to (count, val);
1032}
1033
1034syms_of_insdel ()
1035{
1036 staticpro (&combine_after_change_list);
1037 combine_after_change_list = Qnil;
1038
1039 DEFVAR_LISP ("combine-after-change-calls", &Vcombine_after_change_calls,
1040 "Used internally by the `combine-after-change-calls' macro.");
1041 Vcombine_after_change_calls = Qnil;
1042
1043 defsubr (&Scombine_after_change_execute);
1044}