emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Should invisible imply intangible?


From: Stefan Monnier
Subject: Re: Should invisible imply intangible?
Date: Mon, 04 Mar 2002 20:40:48 -0500

>     >     Also, as David Kastrup has mentioned repeatedly, intangible text 
> tends
>     >     to break lots of things...
>     > 
>     > I don't think so.
> 
>     Please, Richard, try to remember the lengthy discussion we've had about 
> that.
> 
> You seem to agree with my conclusion:
> 
>     In practice, it's generally a non-issue because most uses of intangible
>     text are restricted to a particular context so that this intangible
>     text is only accessed by a small body of elisp code.

As for the patch to adjust_point_for_property, it not only
suffers from the minor problem you mentioned but from the fact that
adjust_point_for_property currently does not take overlays into
account, which makes it useless for outline-style invisible text.

See the attached patch.  It's rather ugly and I'm not convinced it works
100%, although superficial tests show it does work at least in
simple cases (but with overlapping overlays and text properties,
it's less sure).
The code's logic is fairly intricate because it tries (just like
the original code) to avoid redundant work (such as checking the
`composition' property even tho we haven't moved since last time
we checked it).
Maybe I shouldn't be trying so hard ?


        Stefan


Index: keyboard.c
===================================================================
RCS file: /cvsroot/emacs/emacs/src/keyboard.c,v
retrieving revision 1.660
diff -u -u -b -r1.660 keyboard.c
*** keyboard.c  4 Mar 2002 23:40:59 -0000       1.660
--- keyboard.c  5 Mar 2002 01:36:36 -0000
***************
*** 1741,1748 ****
  
  /* Adjust point to a boundary of a region that has such a property
     that should be treated intangible.  For the moment, we check
!    `composition' and `display' property.  LAST_PT is the last position
!    of point.  */
  
  static void
  adjust_point_for_property (last_pt)
--- 1741,1817 ----
  
  /* Adjust point to a boundary of a region that has such a property
     that should be treated intangible.  For the moment, we check
!    `composition', `display' and `invisible' properties.
!    LAST_PT is the last position of point.  */
! 
! static int
! adjust_composition_valid_p (start, end, val)
!      int start, end;
!      Lisp_Object val;
! {
!   return COMPOSITION_VALID_P (start, end, val);
! }
! 
! static int
! adjust_text_prop_means_invisible (start, end, val)
!      int start, end;
!      Lisp_Object val;
! {
!   return TEXT_PROP_MEANS_INVISIBLE (val);
! }
! 
! static int
! adjust_display_prop_intangible_p (start, end, val)
!      int start, end;
!      Lisp_Object val;
! {
!   return display_prop_intangible_p (val);
! }
! 
! static int
! get_property_overlay_and_range (posn, prop, val, start, end)
!      int posn;
!      Lisp_Object prop, *val;
!      int *start, *end;
! {
!   int noverlays;
!   Lisp_Object *overlay_vec, tem;
!   int next_overlay;
!   int len;
!   
!                               /* First try with room for 40 overlays.  */
!   len = 40;
!   overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
!   
!   noverlays = overlays_at (posn, 0, &overlay_vec, &len,
!                          &next_overlay, NULL, 0);
! 
!                               /* If there are more than 40,
!                                  make enough space for all, and try again.  */
!   if (noverlays > len)
!     {
!       len = noverlays;
!       overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
!       noverlays = overlays_at (posn, 0, &overlay_vec, &len,
!                              &next_overlay, NULL, 0);
!     }
!   noverlays = sort_overlays (overlay_vec, noverlays, NULL);
!   
!                               /* Now check the overlays in order of 
decreasing priority.  */
!   while (--noverlays >= 0)
!     {
!       tem = Foverlay_get (overlay_vec[noverlays], prop);
!       if (!NILP (tem))
!       {
!         /* Return the overlay we got the property from.  */
!         *val = tem;
!         *start = XINT (Foverlay_start (overlay_vec[noverlays]));
!         *end = XINT (Foverlay_end (overlay_vec[noverlays]));
!         return 1;
!       }
!     }
!   return 0;
! }
  
  static void
  adjust_point_for_property (last_pt)
***************
*** 1750,1788 ****
  {
    int start, end;
    Lisp_Object val;
!   int check_composition = 1, check_display = 1;
  
!   while (check_composition || check_display)
!     {
!       if (check_composition
!         && PT > BEGV && PT < ZV
!         && get_property_and_range (PT, Qcomposition, &val, &start, &end, Qnil)
!         && COMPOSITION_VALID_P (start, end, val)
!         && start < PT && end > PT
!         && (last_pt <= start || last_pt >= end))
        {
!         if (PT < last_pt)
!           SET_PT (start);
!         else
!           SET_PT (end);
!         check_display = 1;
!       }
!       check_composition = 0;
!       if (check_display
!         && PT > BEGV && PT < ZV
!         && get_property_and_range (PT, Qdisplay, &val, &start, &end, Qnil)
!         && display_prop_intangible_p (val)
          && start < PT && end > PT
          && (last_pt <= start || last_pt >= end))
        {
!         if (PT < last_pt)
!           SET_PT (start);
!         else
!           SET_PT (end);
!         check_composition = 1;
        }
-       check_display = 0;
      }
  }
  
  /* Subroutine for safe_run_hooks: run the hook HOOK.  */
--- 1819,1853 ----
  {
    int start, end;
    Lisp_Object val;
!   struct {
!     Lisp_Object prop; int (*pred) (int, int, Lisp_Object); int overlays;
!   } proptable[] =
!     { { Qcomposition, adjust_composition_valid_p, 0 },
!       { Qinvisible, adjust_text_prop_means_invisible, 1 },
!       { Qdisplay, adjust_display_prop_intangible_p, 1 } };
!   int i = 0, lastdone = 0;
  
!   do
        {
!       int textprop = 1;
!       while (PT > BEGV && PT < ZV
!            && ((proptable[i].overlays
!                 && get_property_overlay_and_range (PT, proptable[i].prop,
!                                                   &val, &start, &end, Qnil)
!                 && (textprop = 1))
!                || (textprop
!                    && (textprop = 0,
!                        get_property_and_range (PT, proptable[i].prop,
!                                                &val, &start, &end, Qnil))))
!            && proptable[i].pred (start, end, val)
          && start < PT && end > PT
          && (last_pt <= start || last_pt >= end))
        {
!         SET_PT (PT < last_pt ? start : end);
!         lastdone = i;
        }
      }
+   while (lastdone != (i = (i + 1) % 3));
  }
  
  /* Subroutine for safe_run_hooks: run the hook HOOK.  */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]