From: Nathaniel Flath <flat0103@gmail.com>
To: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org
Subject: Re: Overalays and point-entered
Date: Tue, 6 Oct 2009 14:33:34 -0400 [thread overview]
Message-ID: <5e3a506e0910061133r3e9b6146l637c84bee7b0d136@mail.gmail.com> (raw)
In-Reply-To: <jwv63b8e81f.fsf-monnier+emacs@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 7129 bytes --]
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: 8294 bytes --]
next prev parent reply other threads:[~2009-10-06 18:33 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 [this message]
2009-10-17 17:00 ` Nathaniel Flath
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=5e3a506e0910061133r3e9b6146l637c84bee7b0d136@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).