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>
Cc: emacs-devel@gnu.org, Miles Bader <miles@gnu.org>
Subject: Re: Overalays and point-entered
Date: Sun, 20 Dec 2009 18:39:15 -0500	[thread overview]
Message-ID: <5e3a506e0912201539p42b7a889v7986f9824df7fbf1@mail.gmail.com> (raw)
In-Reply-To: <jwvaaxr8cwc.fsf-monnier+emacs@gnu.org>


[-- Attachment #1.1: Type: text/plain, Size: 2131 bytes --]

On Thu, Dec 10, 2009 at 3:32 AM, Stefan Monnier <monnier@iro.umontreal.ca>wrote:

> > The patch is attached - please let me know if you have any comments.
>
> I'm wondering whether it should be described as complete or complex.
> Especially for a feature which hsan't yet found a user.
>
>
Yes, I didn't think it would be nearly as complex when I started.   The
latest revision removes the argument for whether it was called due to a
buffer change; this doesn't seem as necessary when the overlay is only run
once instead of multiple times.

> run_point_motion_hooks (prev_c_buffer)

>
> This seems to run the hooks for all overlays at the starting position
> and all overlays at the ending position.  If you add to that the fact
> that it runs them for windows and for the buffer, you get that under the
> usual circumstance of a command within the same buffer displayed in
> a single window, moving within the same overlay we run the hook 4 times?
>
> I think we need to be more careful and only run the hook when crossing
> the boundary, i.e. when moving out of or into an overlay with that
> property.  But even if we decide to run it for all movements, we should
> be careful to run it a bit less liberally.  It's probably OK to
> occasionally have a few spurious extra runs of the hook, but your
> current code needs to be a lot more careful.
>

 The code has been fixed so that the same overlay or text property should
only run once, and only if a boundary has been crossed.  I'm not really sure
whether it should run on all motion; either way would be fairly easy to
implement.

One more thing: I think the buffer and window object should only store
> the few overlays that do have a point-motion property.  Maybe they could
> even limit themselves to storing "the" overlay with a point-motion
> property (if there are several, it should take the one with highest
> priority).
>
>
>
It seemed to be more consistent with the priority mechanism to only store
and run one, so that's what it currently does.   The patch with these fixes
is attached; please let me know if there are any other comments.

Thanks,
Nathaniel Flath

[-- Attachment #1.2: Type: text/html, Size: 2934 bytes --]

[-- Attachment #2: point-motion.patch --]
[-- Type: text/x-patch, Size: 11056 bytes --]

Index: buffer.c
===================================================================
RCS file: /sources/emacs/emacs/src/buffer.c,v
retrieving revision 1.591
diff -u -r1.591 buffer.c
--- buffer.c	21 Nov 2009 11:52:26 -0000	1.591
+++ buffer.c	20 Dec 2009 23:36:42 -0000
@@ -396,7 +396,8 @@
   b->width_run_cache = 0;
   b->width_table = Qnil;
   b->prevent_redisplay_optimizations_p = 1;
-
+  b->prev_text_prop = Qnil;
+  b->overlay_prev = Qnil;
   /* Put this on the chain of all buffers including killed ones.  */
   b->next = all_buffers;
   all_buffers = b;
Index: buffer.h
===================================================================
RCS file: /sources/emacs/emacs/src/buffer.h,v
retrieving revision 1.130
diff -u -r1.130 buffer.h
--- buffer.h	21 Nov 2009 11:52:26 -0000	1.130
+++ buffer.h	20 Dec 2009 23:36:42 -0000
@@ -796,6 +796,13 @@
      t means to use hollow box cursor.
      See `cursor-type' for other values.  */
   Lisp_Object cursor_in_non_selected_windows;
+
+  /* Text property containing point-motion */
+  Lisp_Object prev_text_prop;
+
+  /* Overlay containing point-motion */
+  Lisp_Object overlay_prev;
+
 };

 \f
Index: editfns.c
===================================================================
RCS file: /sources/emacs/emacs/src/editfns.c,v
retrieving revision 1.476
diff -u -r1.476 editfns.c
--- editfns.c	21 Nov 2009 11:52:27 -0000	1.476
+++ editfns.c	20 Dec 2009 23:36:42 -0000
@@ -500,6 +500,48 @@
     }
 }

+/* 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.
Index: keyboard.c
===================================================================
RCS file: /sources/emacs/emacs/src/keyboard.c,v
retrieving revision 1.1024
diff -u -r1.1024 keyboard.c
--- keyboard.c	17 Nov 2009 08:21:35 -0000	1.1024
+++ keyboard.c	20 Dec 2009 23:36:44 -0000
@@ -1522,6 +1522,8 @@

 extern int nonundocount;	/* Declared in cmds.c.  */

+void run_point_motion_hooks();
+
 Lisp_Object
 command_loop_1 ()
 {
@@ -1980,6 +1982,9 @@
 	  && !already_adjusted)
 	adjust_point_for_property (last_point_position, MODIFF != prev_modiff);

+      if (NILP (Vinhibit_point_motion_hooks))
+        run_point_motion_hooks (prev_buffer);
+
       /* Install chars successfully executed in kbd macro.  */

       if (!NILP (current_kboard->defining_kbd_macro)
@@ -1992,6 +1997,154 @@
     }
 }

+/*  Runs 'point-motion hooks on text properties and overlays. */
+void
+run_point_motion_hooks (prev_c_buffer)
+     struct buffer* prev_c_buffer;
+{
+  extern Lisp_Object Qpoint_motion, Qwindow, Qpriority;
+
+  static Lisp_Object prev_window;
+  static Lisp_Object prev_buffer;
+  static struct window* prev_c_window;
+
+  int i, j, noverlays_cur;
+  Lisp_Object point_motion, overlay_window;
+  struct window* current_window = XWINDOW (Fselected_window());
+  int run_overlay, run_text_prop;
+  Lisp_Object text_properties[5];
+  Lisp_Object overlays[5];
+
+  Lisp_Object *overlay_cur_vec;
+  Lisp_Object current_overlay;
+
+  /* Retrieves vector of overlays in current location and uses this to
+     find the 'current' overlay to run */
+  overlay_cur_vec = get_overlays_at_pos (make_number (current_buffer->pt),
+                                         current_buffer,
+                                         &noverlays_cur);
+  current_overlay = Qnil;
+  for (i = 0; i < noverlays_cur; i++)
+    {
+      Lisp_Object pm = Foverlay_get (overlay_cur_vec[i], Qpoint_motion);
+      if (!NILP (pm)) {
+        if (NILP (current_overlay))
+          {
+            current_overlay = overlay_cur_vec[i];
+            continue;
+          }
+        Lisp_Object cur_priority = Foverlay_get (current_overlay, Qpriority);
+        Lisp_Object tmp_priority = Foverlay_get (overlay_cur_vec[i], Qpriority);
+        if ( NILP (cur_priority)
+            || (!NILP (tmp_priority)
+                && XINT (cur_priority) < XINT (tmp_priority)))
+              {
+                current_overlay = overlay_cur_vec[i];
+              }
+        }
+    }
+
+  /* Runs the 'point-motion property for unique overlays */
+  if (NILP (Feq (Fcurrent_buffer(), prev_buffer))
+      || NILP (Feq (Fselected_window(), prev_window))
+      || NILP (Feq (current_overlay, prev_c_buffer->overlay_prev)))
+    {
+      overlays[0] = current_overlay;
+      overlays[1] = current_buffer->overlay_prev;
+      overlays[2] = current_window->overlay_prev;
+      overlays[3] = Qnil;
+      overlays[4] = Qnil;
+      if (prev_c_buffer)
+        overlays[3] = prev_c_buffer->overlay_prev;
+      if (prev_c_window)
+        overlays[4] = prev_c_window->overlay_prev;
+
+      for (i = 0; i < 5; i++)
+        {
+          run_overlay = 1;
+          if (NILP (overlays[i])) continue;
+          for (j = 0; j < i; j++)
+            {
+              if (!NILP (Feq (overlays[i], overlays[j]))) {
+                run_overlay = 0;
+                break;
+              }
+            }
+          if (run_overlay)
+            {
+              point_motion = Foverlay_get (overlays[i], Qpoint_motion);
+              overlay_window = Foverlay_get (overlays[i], Qwindow);
+              if (!NILP (point_motion)
+                  && (NILP (overlay_window)
+                      || !NILP (Feq (overlay_window, Fselected_window()))))
+                {
+                  call5 (point_motion,
+                         make_number (last_point_position),
+                         make_number (current_buffer->pt),
+                         overlays[i],
+                         prev_buffer,
+                         prev_window);
+                }
+            }
+        }
+    }
+
+  /* Get text properties to run */
+  text_properties[0] = Fget_text_property (make_number (current_buffer->pt),
+                                           Qpoint_motion,
+                                           Qnil);
+  text_properties[1] = current_buffer->prev_text_prop;
+  text_properties[2] = current_window->prev_text_prop;
+  text_properties[3] = Qnil;
+  text_properties[4] = Qnil;
+  if (prev_c_buffer) {
+    text_properties[3] = prev_c_buffer->prev_text_prop;
+  }
+  if (prev_c_window) {
+    text_properties[4] = prev_c_window->prev_text_prop;
+  }
+
+  /* Runs point-motion of text properties */
+  if (NILP (Feq (Fcurrent_buffer(), prev_buffer))
+      || NILP (Feq (Fselected_window(), prev_window))
+      || NILP (Feq (text_properties[0], prev_c_buffer->prev_text_prop)))
+    {
+      for (i = 0; i < 5; i++)
+        {
+          run_text_prop = 1;
+          for (j = 0; j < i; j++)
+            {
+              if (!NILP (Feq (text_properties[i], text_properties[j])))
+                {
+                  run_text_prop = 0;
+                  break;
+                }
+            }
+          if (run_text_prop == 1 && !NILP (text_properties[i]))
+            {
+              call5 (text_properties[i],
+                     make_number (last_point_position),
+                     make_number (current_buffer->pt),
+                     text_properties[i],
+                     prev_buffer,
+                     prev_window );
+            }
+        }
+    }
+
+  /* Sets previous overlays and text properties */
+  current_buffer->overlay_prev = current_overlay;
+  current_window->overlay_prev = current_overlay;
+
+  current_buffer->prev_text_prop = text_properties[0];
+  current_window->prev_text_prop = text_properties[0];
+
+  prev_window = Fselected_window();
+  prev_c_window = XWINDOW (Fselected_window());
+  prev_buffer = Fcurrent_buffer();
+}
+
 extern Lisp_Object Qcomposition, Qdisplay;

 /* Adjust point to a boundary of a region that has such a property
Index: textprop.c
===================================================================
RCS file: /sources/emacs/emacs/src/textprop.c,v
retrieving revision 1.167
diff -u -r1.167 textprop.c
--- textprop.c	6 Nov 2009 06:50:59 -0000	1.167
+++ textprop.c	20 Dec 2009 23:36:44 -0000
@@ -54,6 +54,7 @@
 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;
@@ -2349,6 +2350,8 @@
   Qpoint_left = intern_c_string ("point-left");
   staticpro (&Qpoint_entered);
   Qpoint_entered = intern_c_string ("point-entered");
+  staticpro (&Qpoint_motion);
+  Qpoint_motion = intern_c_string("point-motion");

   defsubr (&Stext_properties_at);
   defsubr (&Sget_text_property);
Index: window.c
===================================================================
RCS file: /sources/emacs/emacs/src/window.c,v
retrieving revision 1.644
diff -u -r1.644 window.c
--- window.c	6 Nov 2009 06:50:59 -0000	1.644
+++ window.c	20 Dec 2009 23:36:45 -0000
@@ -267,7 +267,8 @@
   p->scroll_bar_width = Qnil;
   p->vertical_scroll_bar_type = Qt;
   p->resize_proportionally = Qnil;
+  p->prev_text_prop = Qnil;
+  p->overlay_prev = Qnil;
+
   Vwindow_list = Qnil;
   return val;
 }
Index: window.h
===================================================================
RCS file: /sources/emacs/emacs/src/window.h,v
retrieving revision 1.81
diff -u -r1.81 window.h
--- window.h	8 Jan 2009 03:16:09 -0000	1.81
+++ window.h	20 Dec 2009 23:36:45 -0000
@@ -292,6 +292,12 @@
     /* Z_BYTE - the buffer position of the last glyph in the current matrix
        of W.  Only valid if WINDOW_END_VALID is not nil.  */
     int window_end_bytepos;
+
+    /* Last overlay run containing point-motion */
+    Lisp_Object overlay_prev;
+
+    /* Text property containing point-motion */
+    Lisp_Object prev_text_prop;
 };

 /* 1 if W is a minibuffer window.  */

  reply	other threads:[~2009-12-20 23:39 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
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 [this message]
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=5e3a506e0912201539p42b7a889v7986f9824df7fbf1@mail.gmail.com \
    --to=flat0103@gmail.com \
    --cc=emacs-devel@gnu.org \
    --cc=miles@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).