comparison src/buffer.c @ 12538:5920994b14c2

(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.
author Karl Heuer <kwzh@gnu.org>
date Mon, 17 Jul 1995 22:19:07 +0000
parents 71aa23be0228
children 9ebf33d6d07c
comparison
equal deleted inserted replaced
12537:476296adb950 12538:5920994b14c2
2991 Fdelete_overlay (overlay); 2991 Fdelete_overlay (overlay);
2992 } 2992 }
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. */
3007 static Lisp_Object last_overlay_modification_hooks;
3008
3009 /* Number of elements actually used in last_overlay_modification_hooks. */
3010 static int last_overlay_modification_hooks_used;
3011
3012 /* Add one functionlist/overlay pair
3013 to the end of last_overlay_modification_hooks. */
3014
3015 static void
3016 add_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
3006 void 3049 void
3007 report_overlay_modification (start, end, after, arg1, arg2, arg3) 3050 report_overlay_modification (start, end, after, arg1, arg2, arg3)
3008 Lisp_Object start, end; 3051 Lisp_Object start, end;
3009 int after; 3052 int after;
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
3017 overlay = Qnil; 3061 overlay = Qnil;
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);
3024 tail = XCONS (tail)->cdr) 3097 tail = XCONS (tail)->cdr)
3025 { 3098 {
3032 oend = OVERLAY_END (overlay); 3105 oend = OVERLAY_END (overlay);
3033 endpos = OVERLAY_POSITION (oend); 3106 endpos = OVERLAY_POSITION (oend);
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))
3041 { 3115 {
3042 /* Copy TAIL in case the hook recenters the overlay lists. */ 3116 /* Copy TAIL in case the hook recenters the overlay lists. */
3044 tail = Fcopy_sequence (tail); 3118 tail = Fcopy_sequence (tail);
3045 tail_copied = 1; 3119 tail_copied = 1;
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))
3053 { 3128 {
3054 if (!tail_copied) 3129 if (!tail_copied)
3086 oend = OVERLAY_END (overlay); 3161 oend = OVERLAY_END (overlay);
3087 startpos = OVERLAY_POSITION (ostart); 3162 startpos = OVERLAY_POSITION (ostart);
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))
3095 { 3171 {
3096 if (!tail_copied) 3172 if (!tail_copied)
3097 tail = Fcopy_sequence (tail); 3173 tail = Fcopy_sequence (tail);
3098 tail_copied = 1; 3174 tail_copied = 1;
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))
3106 { 3183 {
3107 if (!tail_copied) 3184 if (!tail_copied)
3133 Lisp_Object list, overlay; 3210 Lisp_Object list, overlay;
3134 int after; 3211 int after;
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))
3142 call4 (Fcar (list), overlay, after ? Qt : Qnil, arg1, arg2); 3223 call4 (Fcar (list), overlay, after ? Qt : Qnil, arg1, arg2);
3143 else 3224 else
3373 3454
3374 /* initialize the buffer routines */ 3455 /* initialize the buffer routines */
3375 syms_of_buffer () 3456 syms_of_buffer ()
3376 { 3457 {
3377 extern Lisp_Object Qdisabled; 3458 extern Lisp_Object Qdisabled;
3459
3460 staticpro (&last_overlay_modification_hooks);
3461 last_overlay_modification_hooks
3462 = Fmake_vector (make_number (10), Qnil);
3378 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);
3382 staticpro (&Qmode_class); 3467 staticpro (&Qmode_class);