unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
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 --]

  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).