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: Tue, 05 Mar 2002 18:34:38 -0500

> > I wrote
> > 
> >     The change in adjust_point_for_property seems ok, and it might solve
> >     this problem.
> > 
> > However, subsequently I realized it should be somewhat different.  The
> > buffer position just after the invisible text should be treated as
> > part of the range where point cannot be.  (This is how invisible,
> > intangible text is handled now.)
> 
> But that would make it very awkward for the user to insert text
> immediately after the invisible area.
> 
> If we still want to provide the illusion that the text really isn't
> there at all, then we should treat either the buffer position
> immediately before or immediately after as part of the intangible text,
> depending on the direction of the motion (so that both positions
> can still be reached "easily").

And here is a patch that does just that.
Note that there are two (related) problems left:
- when the text is replaced by an ellipsis, the cursor is always drawn
  after the ellipsis even if point is immediately *before* the invisible text.
- I feel like this new "pretend the text isn't there at all" behavior
  works well for completely invisible text, but not for text with an
  elipsis where it makes sense for C-f or C-b to only skip over
  the hidden text rather than "the hidden text + 1".

Of course, the second point would be even more relevant if the first point
was addressed.


        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 23:28:44 -0000
***************
*** 1741,1788 ****
  
  /* 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)
       int last_pt;
  {
    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.  */
--- 1741,1814 ----
  
  /* 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 void
  adjust_point_for_property (last_pt)
       int last_pt;
  {
    int start, end;
!   Lisp_Object val, overlay;
!   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
!                 && (val = get_char_property_and_overlay (make_number (PT),
!                                                          proptable[i].prop,
!                                                          Qnil, &overlay),
!                     start = NILP (overlay)
!                             ? 0 : XINT (Foverlay_start (overlay)),
!                     end = NILP (overlay) ? 0 : XINT (Foverlay_end (overlay)),
!                     !NILP (val) && !NILP (overlay))
!                 && (textprop = 1))
!                || (textprop
!                    && (textprop = 0,
!                        get_property_and_range (PT, proptable[i].prop,
!                                                &val, &start, &end, Qnil))))
!            && proptable[i].pred (start, end, val)
!            && (PT < last_pt
!                ? (start <= PT && end > PT) : (start < PT && end >= PT))
          && (last_pt <= start || last_pt >= end))
        {
!         SET_PT (PT < last_pt ? max (start - 1, BEGV) : min (end + 1, ZV));
!         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]