Any comments ont his? Thanks, Nathaniel Flath On Tue, Oct 6, 2009 at 2:33 PM, Nathaniel Flath wrote: > Sorry for taking so long on this - I ended up being pretty busy with school > and couldn't work on it for a while. > > I added a function get_overlays_at_pos which will return a list of overlays > active at the given position and buffer - the design is based on > get_pos_property. Then at the end of command_loop_1, > run_point_motion_hooks is called which will retrieve the overlays at the > current position, run the 'point-motion' property with the old point, new > point, and overlay, and then run property for all overlays which were just > executed. The 'point-motion property is also executed for the text property > at current point, and the previous point's text-property if it is different > from the one at current point. > > The diff for this is below - let me know your thoughts. > > Thanks, > Nathaniel Flath > > diff --git a/src/editfns.c b/src/editfns.c > index e52c3c2..7f343f0 100644 > --- a/src/editfns.c > +++ b/src/editfns.c > @@ -499,6 +499,48 @@ get_pos_property (position, prop, object) > } > } > > +/* Returns an array of overlays that are active at the indication position > and buffer. > + The lenght of the array will be stored in num_overlays. */ > + > +Lisp_Object* > +get_overlays_at_pos (position, buffer, num_overlays ) > + Lisp_Object position, buffer; > + int* num_overlays; > +{ > + CHECK_NUMBER_COERCE_MARKER (position); > + > + if (NILP (buffer)) > + XSETBUFFER (buffer, current_buffer); > + > + int posn = XINT (position); > + int i, noverlays; > + Lisp_Object* overlay_vec; > + struct buffer *obuf = current_buffer; > + set_buffer_temp (XBUFFER (buffer)); > + > + noverlays = overlays_around (posn, overlay_vec, 0); > + overlay_vec = xmalloc (sizeof(Lisp_Object) * noverlays); > + noverlays = overlays_around (posn, overlay_vec, noverlays); > + noverlays = sort_overlays (overlay_vec, noverlays, NULL); > + > + set_buffer_temp (obuf); > + for (i = 0; i < noverlays; i++) > + { > + Lisp_Object ol = overlay_vec[i]; > + Lisp_Object start = OVERLAY_START (ol), finish = OVERLAY_END (ol); > + if ((OVERLAY_POSITION (start) == posn > + && XMARKER (start)->insertion_type == 1) > + || (OVERLAY_POSITION (finish) == posn > + && XMARKER (finish)->insertion_type == 0)) > + { > + overlay_vec[i] = overlay_vec[noverlays]; > + noverlays--; i--; > + } > + } > + *num_overlays = noverlays; > + return overlay_vec; > +} > + > /* Find the field surrounding POS in *BEG and *END. If POS is nil, > the value of point is used instead. If BEG or END is null, > means don't store the beginning or end of the field. > > > > > diff --git a/src/textprop.c b/src/textprop.c > index 0018088..5708040 100644 > --- a/src/textprop.c > +++ b/src/textprop.c > @@ -53,6 +53,7 @@ Lisp_Object Qpoint_left; > Lisp_Object Qpoint_entered; > Lisp_Object Qcategory; > Lisp_Object Qlocal_map; > +Lisp_Object Qpoint_motion; > > /* Visual properties text (including strings) may have. */ > Lisp_Object Qforeground, Qbackground, Qfont, Qunderline, Qstipple; > @@ -2348,6 +2349,9 @@ inherits it if NONSTICKINESS is nil. The > `front-sticky' and > Qpoint_left = intern ("point-left"); > staticpro (&Qpoint_entered); > Qpoint_entered = intern ("point-entered"); > + staticpro (&Qpoint_entered); > + Qpoint_motion = intern ("point-motion"); > + > > defsubr (&Stext_properties_at); > defsubr (&Sget_text_property); > > > > > diff --git a/src/keyboard.c b/src/keyboard.c > index 35c338c..a375daf 100644 > --- a/src/keyboard.c > +++ b/src/keyboard.c > @@ -1989,6 +1993,93 @@ command_loop_1 () > } > } > > +/* Runs 'point-motion hooks on text properties and overlays.*/ > + > +void > +run_point_motion_hooks () > +{ > + static Lisp_Object* overlay_prev_vec; > + static Lisp_Object prev_text_prop; > + static int noverlays_prev; > + > + int i, j, noverlays_cur; > + Lisp_Object *overlay_cur_vec; > + Lisp_Object point_motion, overlay_window; > + extern Lisp_Object Qpoint_motion, Qwindow; > + > + /* Retrieves vector of overlays in current location and runs > 'point-motion > + hook for those whose 'window property allows it to be displayed */ > + overlay_cur_vec = get_overlays_at_pos (make_number (current_buffer->pt), > + current_buffer, > + &noverlays_cur); > + for (i = 0; i < noverlays_cur; i++) > + { > + point_motion = Foverlay_get (overlay_cur_vec[i], Qpoint_motion); > + overlay_window = Foverlay_get (overlay_cur_vec[i], Qwindow); > + if (!NILP (point_motion) && > + (NILP (overlay_window) > + || !NILP (Feq (overlay_window, Fselected_window())))) > + { > + call3 (point_motion, > + make_number (last_point_position), > + make_number (current_buffer->pt), > + overlay_cur_vec[i]); > + } > + } > + > + /* Runs hooks for all overlays that the point used to be in but no > longer is */ > + for (i = 0; i < noverlays_prev; i++) > + { > + point_motion = Foverlay_get (overlay_prev_vec[i], Qpoint_motion); > + overlay_window = Foverlay_get (overlay_prev_vec[i], Qwindow); > + if (!NILP (point_motion) && > + (NILP (overlay_window) > + || !NILP (Feq (overlay_window, Fselected_window())))) > + { > + for (j = 0; noverlays_cur; j++) { > + if (!NILP (Feq (overlay_prev_vec[i], overlay_cur_vec[j]))) > + goto next; > + } > + > + call3 (point_motion, > + make_number (last_point_position), > + make_number (current_buffer->pt), > + overlay_prev_vec[i]); > + next: i=i; > + } > + } > + > + /* Runs hook for current text property */ > + point_motion = Fget_text_property (make_number (current_buffer->pt), > + Qpoint_motion, > + Qnil); > + if (!NILP (point_motion)) > + { > + call3 (point_motion, > + make_number (last_point_position), > + make_number (current_buffer->pt), > + Fcurrent_buffer()); > + } > + > + /* Runs hook for previous text property if it is different than the > current text property */ > + if (prev_text_prop != 0 && !NILP (prev_text_prop)) { > + if (NILP (Feq (prev_text_prop, point_motion))) > + { > + call3 (prev_text_prop, > + make_number (last_point_position), > + make_number (current_buffer->pt), > + Fcurrent_buffer()); > + } > + } > + > + prev_text_prop = point_motion; > + > + /* Frees previous overlays and sets them to the current list */ > + free (overlay_prev_vec); > + overlay_prev_vec = overlay_cur_vec; > + noverlays_prev = noverlays_cur; > +} > + > extern Lisp_Object Qcomposition, Qdisplay; > > /* Adjust point to a boundary of a region that has such a property > > > On Thu, Sep 24, 2009 at 10:26 AM, Stefan Monnier > wrote: > >> > Never mind, since get_pos_property is a C function and not a Lisp one >> this >> > probably wouldn't work. >> >> That's OK. It can still return a list, or else an array. >> But if it can return the overlays rather than the property's values, >> then you could pass the overlay back to the hook functions, which would >> probably be convnient for those functions. >> >> >> Stefan >> > >