aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
authorKarl Heuer1995-07-17 22:19:07 +0000
committerKarl Heuer1995-07-17 22:19:07 +0000
commit9115729ea3ea049e00e9e72cae09095c593e131a (patch)
tree206b4d92491b3158e0971222fa392061358bc01a /src/buffer.c
parent9a51b24a036009390f5ced5ae8932d4a89e63690 (diff)
downloademacs-9115729ea3ea049e00e9e72cae09095c593e131a.tar.gz
emacs-9115729ea3ea049e00e9e72cae09095c593e131a.zip
(last_overlay_modification_hooks): New variable.
(last_overlay_modification_hooks_used): Likewise. (syms_of_buffer): Init last_overlay_modification_hooks. (add_overlay_mod_hooklist): New function. (call_overlay_mod_hooks): Call add_overlay_mod_hooklist. (report_overlay_modification): When AFTER is non-nil, call the functions recorded in last_overlay_modification_hooks.
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c99
1 files changed, 92 insertions, 7 deletions
diff --git a/src/buffer.c b/src/buffer.c
index f4ede7c8e56..c5a58429ef3 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2993,15 +2993,58 @@ DEFUN ("overlay-put", Foverlay_put, Soverlay_put, 3, 3, 0,
2993 return value; 2993 return value;
2994} 2994}
2995 2995
2996/* Subroutine of report_overlay_modification. */
2997
2998/* Lisp vector holding overlay hook functions to call.
2999 Vector elements come in pairs.
3000 Each even-index element is a list of hook functions.
3001 The following odd-index element is the overlay they came from.
3002
3003 Before the buffer change, we fill in this vector
3004 as we call overlay hook functions.
3005 After the buffer change, we get the functions to call from this vector.
3006 This way we always call the same functions before and after the change. */
3007static Lisp_Object last_overlay_modification_hooks;
3008
3009/* Number of elements actually used in last_overlay_modification_hooks. */
3010static int last_overlay_modification_hooks_used;
3011
3012/* Add one functionlist/overlay pair
3013 to the end of last_overlay_modification_hooks. */
3014
3015static void
3016add_overlay_mod_hooklist (functionlist, overlay)
3017 Lisp_Object functionlist, overlay;
3018{
3019 int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
3020
3021 if (last_overlay_modification_hooks_used == oldsize)
3022 {
3023 Lisp_Object old;
3024 old = last_overlay_modification_hooks;
3025 last_overlay_modification_hooks
3026 = Fmake_vector (make_number (oldsize * 2), Qnil);
3027 bcopy (XVECTOR (last_overlay_modification_hooks)->contents,
3028 XVECTOR (old)->contents,
3029 sizeof (Lisp_Object) * oldsize);
3030 }
3031 XVECTOR (last_overlay_modification_hooks)->contents[last_overlay_modification_hooks_used++] = functionlist;
3032 XVECTOR (last_overlay_modification_hooks)->contents[last_overlay_modification_hooks_used++] = overlay;
3033}
3034
2996/* Run the modification-hooks of overlays that include 3035/* Run the modification-hooks of overlays that include
2997 any part of the text in START to END. 3036 any part of the text in START to END.
2998 Run the insert-before-hooks of overlay starting at END, 3037 If this change is an insertion, also
3038 run the insert-before-hooks of overlay starting at END,
2999 and the insert-after-hooks of overlay ending at START. 3039 and the insert-after-hooks of overlay ending at START.
3000 3040
3001 This is called both before and after the modification. 3041 This is called both before and after the modification.
3002 AFTER is nonzero when we call after the modification. 3042 AFTER is nonzero when we call after the modification.
3003 3043
3004 ARG1, ARG2, ARG3 are arguments to pass to the hook functions. */ 3044 ARG1, ARG2, ARG3 are arguments to pass to the hook functions.
3045 When AFTER is nonzero, they are the start position,
3046 the position after the inserted new text,
3047 and the length of deleted or replaced old text. */
3005 3048
3006void 3049void
3007report_overlay_modification (start, end, after, arg1, arg2, arg3) 3050report_overlay_modification (start, end, after, arg1, arg2, arg3)
@@ -3010,7 +3053,8 @@ report_overlay_modification (start, end, after, arg1, arg2, arg3)
3010 Lisp_Object arg1, arg2, arg3; 3053 Lisp_Object arg1, arg2, arg3;
3011{ 3054{
3012 Lisp_Object prop, overlay, tail; 3055 Lisp_Object prop, overlay, tail;
3013 int insertion = EQ (start, end); 3056 /* 1 if this change is an insertion. */
3057 int insertion = (after ? XFASTINT (arg3) == 0 : EQ (start, end));
3014 int tail_copied; 3058 int tail_copied;
3015 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; 3059 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
3016 3060
@@ -3018,6 +3062,35 @@ report_overlay_modification (start, end, after, arg1, arg2, arg3)
3018 tail = Qnil; 3062 tail = Qnil;
3019 GCPRO5 (overlay, tail, arg1, arg2, arg3); 3063 GCPRO5 (overlay, tail, arg1, arg2, arg3);
3020 3064
3065 if (after)
3066 {
3067 /* Call the functions recorded in last_overlay_modification_hooks
3068 rather than scanning the overlays again.
3069 First copy the vector contents, in case some of these hooks
3070 do subsequent modification of the buffer. */
3071 int size = last_overlay_modification_hooks_used;
3072 Lisp_Object *copy = (Lisp_Object *) alloca (size * sizeof (Lisp_Object));
3073 int i;
3074
3075 bcopy (XVECTOR (last_overlay_modification_hooks)->contents,
3076 copy, size * sizeof (Lisp_Object));
3077 gcpro1.var = copy;
3078 gcpro1.nvars = size;
3079
3080 for (i = 0; i < size;)
3081 {
3082 Lisp_Object prop, overlay;
3083 prop = copy[i++];
3084 overlay = copy[i++];
3085 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
3086 }
3087 UNGCPRO;
3088 return;
3089 }
3090
3091 /* We are being called before a change.
3092 Scan the overlays to find the functions to call. */
3093 last_overlay_modification_hooks_used = 0;
3021 tail_copied = 0; 3094 tail_copied = 0;
3022 for (tail = current_buffer->overlays_before; 3095 for (tail = current_buffer->overlays_before;
3023 CONSP (tail); 3096 CONSP (tail);
@@ -3034,7 +3107,8 @@ report_overlay_modification (start, end, after, arg1, arg2, arg3)
3034 if (XFASTINT (start) > endpos) 3107 if (XFASTINT (start) > endpos)
3035 break; 3108 break;
3036 startpos = OVERLAY_POSITION (ostart); 3109 startpos = OVERLAY_POSITION (ostart);
3037 if (XFASTINT (end) == startpos && insertion) 3110 if (insertion && (XFASTINT (start) == startpos
3111 || XFASTINT (end) == startpos))
3038 { 3112 {
3039 prop = Foverlay_get (overlay, Qinsert_in_front_hooks); 3113 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
3040 if (!NILP (prop)) 3114 if (!NILP (prop))
@@ -3046,7 +3120,8 @@ report_overlay_modification (start, end, after, arg1, arg2, arg3)
3046 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3); 3120 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
3047 } 3121 }
3048 } 3122 }
3049 if (XFASTINT (start) == endpos && insertion) 3123 if (insertion && (XFASTINT (start) == endpos
3124 || XFASTINT (end) == endpos))
3050 { 3125 {
3051 prop = Foverlay_get (overlay, Qinsert_behind_hooks); 3126 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
3052 if (!NILP (prop)) 3127 if (!NILP (prop))
@@ -3088,7 +3163,8 @@ report_overlay_modification (start, end, after, arg1, arg2, arg3)
3088 endpos = OVERLAY_POSITION (oend); 3163 endpos = OVERLAY_POSITION (oend);
3089 if (XFASTINT (end) < startpos) 3164 if (XFASTINT (end) < startpos)
3090 break; 3165 break;
3091 if (XFASTINT (end) == startpos && insertion) 3166 if (insertion && (XFASTINT (start) == startpos
3167 || XFASTINT (end) == startpos))
3092 { 3168 {
3093 prop = Foverlay_get (overlay, Qinsert_in_front_hooks); 3169 prop = Foverlay_get (overlay, Qinsert_in_front_hooks);
3094 if (!NILP (prop)) 3170 if (!NILP (prop))
@@ -3099,7 +3175,8 @@ report_overlay_modification (start, end, after, arg1, arg2, arg3)
3099 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3); 3175 call_overlay_mod_hooks (prop, overlay, after, arg1, arg2, arg3);
3100 } 3176 }
3101 } 3177 }
3102 if (XFASTINT (start) == endpos && insertion) 3178 if (insertion && (XFASTINT (start) == endpos
3179 || XFASTINT (end) == endpos))
3103 { 3180 {
3104 prop = Foverlay_get (overlay, Qinsert_behind_hooks); 3181 prop = Foverlay_get (overlay, Qinsert_behind_hooks);
3105 if (!NILP (prop)) 3182 if (!NILP (prop))
@@ -3135,7 +3212,11 @@ call_overlay_mod_hooks (list, overlay, after, arg1, arg2, arg3)
3135 Lisp_Object arg1, arg2, arg3; 3212 Lisp_Object arg1, arg2, arg3;
3136{ 3213{
3137 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 3214 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3215
3138 GCPRO4 (list, arg1, arg2, arg3); 3216 GCPRO4 (list, arg1, arg2, arg3);
3217 if (! after)
3218 add_overlay_mod_hooklist (list, overlay);
3219
3139 while (!NILP (list)) 3220 while (!NILP (list))
3140 { 3221 {
3141 if (NILP (arg3)) 3222 if (NILP (arg3))
@@ -3376,6 +3457,10 @@ syms_of_buffer ()
3376{ 3457{
3377 extern Lisp_Object Qdisabled; 3458 extern Lisp_Object Qdisabled;
3378 3459
3460 staticpro (&last_overlay_modification_hooks);
3461 last_overlay_modification_hooks
3462 = Fmake_vector (make_number (10), Qnil);
3463
3379 staticpro (&Vbuffer_defaults); 3464 staticpro (&Vbuffer_defaults);
3380 staticpro (&Vbuffer_local_symbols); 3465 staticpro (&Vbuffer_local_symbols);
3381 staticpro (&Qfundamental_mode); 3466 staticpro (&Qfundamental_mode);