From: Nathaniel Flath <flat0103@gmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org
Subject: Re: Overalays and point-entered
Date: Sat, 17 Oct 2009 13:00:47 -0400 [thread overview]
Message-ID: <5e3a506e0910171000n79e9c992n6c243fc0f42a919a@mail.gmail.com> (raw)
In-Reply-To: <5e3a506e0910061133r3e9b6146l637c84bee7b0d136@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 7671 bytes --]
Any comments ont his?
Thanks,
Nathaniel Flath
On Tue, Oct 6, 2009 at 2:33 PM, Nathaniel Flath <flat0103@gmail.com> 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 <monnier@iro.umontreal.ca
> > 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
>>
>
>
[-- Attachment #2: Type: text/html, Size: 8790 bytes --]
next prev parent reply other threads:[~2009-10-17 17:00 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-09-11 0:09 Overalays and point-entered Nathaniel Flath
2009-09-11 1:57 ` Stefan Monnier
[not found] ` <5e3a506e0909101902h72747299u2e306830ce63b11d@mail.gmail.com>
[not found] ` <jwvmy52p4re.fsf-monnier+emacs@gnu.org>
2009-09-11 4:08 ` Nathaniel Flath
2009-09-13 16:47 ` Nathaniel Flath
2009-09-14 1:16 ` Stefan Monnier
[not found] ` <5e3a506e0909140810r38a83a84l387fb6bafeb962c1@mail.gmail.com>
[not found] ` <jwvzl8x49un.fsf-monnier+emacs@gnu.org>
2009-09-16 20:46 ` Nathaniel Flath
2009-09-17 1:05 ` Stefan Monnier
2009-09-23 15:41 ` Nathaniel Flath
2009-09-23 20:55 ` Stefan Monnier
2009-09-24 1:07 ` Stephen J. Turnbull
2009-09-24 14:31 ` Overlays " Stefan Monnier
2009-09-24 13:47 ` Overalays " Nathaniel Flath
2009-09-24 14:04 ` Nathaniel Flath
2009-09-24 14:26 ` Stefan Monnier
2009-10-06 18:33 ` Nathaniel Flath
2009-10-17 17:00 ` Nathaniel Flath [this message]
2009-10-18 1:09 ` Stefan Monnier
2009-10-22 3:35 ` Nathaniel Flath
2009-10-22 15:37 ` Stefan Monnier
2009-10-23 15:43 ` Nathaniel Flath
2009-10-25 2:30 ` Stefan Monnier
2009-10-27 8:42 ` Nathaniel Flath
2009-10-27 13:28 ` Stefan Monnier
2009-10-28 0:44 ` Miles Bader
2009-10-31 17:03 ` Nathaniel Flath
2009-11-06 14:54 ` Nathaniel Flath
2009-12-09 23:41 ` Nathaniel Flath
2009-12-10 3:37 ` Nathaniel Flath
2009-12-10 8:32 ` Stefan Monnier
2009-12-20 23:39 ` Nathaniel Flath
2010-01-02 3:34 ` Nathaniel Flath
2010-01-08 7:19 ` Nathaniel Flath
2010-01-15 2:38 ` Stefan Monnier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5e3a506e0910171000n79e9c992n6c243fc0f42a919a@mail.gmail.com \
--to=flat0103@gmail.com \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).