diff options
| author | Karl Heuer | 1995-07-17 22:19:07 +0000 |
|---|---|---|
| committer | Karl Heuer | 1995-07-17 22:19:07 +0000 |
| commit | 9115729ea3ea049e00e9e72cae09095c593e131a (patch) | |
| tree | 206b4d92491b3158e0971222fa392061358bc01a /src/buffer.c | |
| parent | 9a51b24a036009390f5ced5ae8932d4a89e63690 (diff) | |
| download | emacs-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.c | 99 |
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. */ | ||
| 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) |
| @@ -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); |