emacs-devel
[Top][All Lists]
Advanced

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

Re: Feature request : Tab-completion for 'shell-comand'


From: martin rudalics
Subject: Re: Feature request : Tab-completion for 'shell-comand'
Date: Fri, 14 Mar 2008 08:46:24 +0100
User-agent: Mozilla Thunderbird 1.0 (Windows/20041206)

> The doc string of `remove-overlays' doesn't make it precisely clear
> what the criterion is for removing an overlay.  Perhaps that criterion
> needs to be changed.  It is worth some thought.

The doc-string of `remove-overlays' is not useful in this regard - its
first sentence is silly.  But `remove-overlays' relies on `overlays-in'
and the latter's doc-string is precise.  A zero-length overlay located
at the (implicit) END arg of `remove-overlays' should _not_ get deleted
unless it's located at the (implicit) BEG too.

`remove-overlays' is more often used for the wrong purpose - to delete
all overlays (with a given property) in a buffer.  As I suggested
earlier some form of `delete-all-overlays' would serve that purpose much
better - in particular it wouldn't have to build and subsequently gc the
intermediate list returned by `overlays-in'.  Moreover it wouldn't have
to recenter overlays and could be easily instructed to delete overlays
with given properties only.

OTOH `overlays-in' disregards overlay properties.  This contrasts with
its actual use in Emacs: The vast majority of `overlays-in' calls is
followed by code checking whether the returned overlays match some
specific property.  This approach is highly inefficient when a buffer
contains few overlays with property foo, many with property bar, and a
client is looking for all overlays with property foo.  `overlays-in'
must investigate all overlays (find their start and end points, compare
whether they fit into the region, maybe allocate an additional vector)
and put them together in a list.  The client has to filter the list
returned and the collector has to recycle it.

I attached an older patch I found useful in this context.  `overlays-in'
would get an additional optional parameter PROP and include an overlay
iff either PROP is nil or its property list has an entry for PROP.
`overlays-with-prop-eq-value' would get two additional parameters PROP
and VALUE and include an overlay only if its PROP property eqs VALUE.

People then could start to get rid of monstrosities like

            (let ((pos (point-min)))
              (while (< (setq pos (next-overlay-change pos)) (point-max))
                (dolist (ol (overlays-at pos))
                  (if (overlay-get ol 'sgml-tag)
                      (delete-overlay ol)))))

in sgml-mode.

*** buffer.c.~1.541.~   Wed Nov 28 05:46:22 2007
--- buffer.c    Mon Jan 14 19:58:34 2008
***************
*** 2679,2691 ****
     If EXTEND is non-zero, we make the vector bigger if necessary.
     If EXTEND is zero, we never extend the vector,
     and we store only as many overlays as will fit.
!    But we still return the total number of overlays.  */
  
  static int
! overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr)
       int beg, end;
       int extend;
       Lisp_Object **vec_ptr;
       int *len_ptr;
       int *next_ptr;
       int *prev_ptr;
--- 2679,2700 ----
     If EXTEND is non-zero, we make the vector bigger if necessary.
     If EXTEND is zero, we never extend the vector,
     and we store only as many overlays as will fit.
!    But we still return the total number of overlays.
! 
!    CHECK should be 0, 1 or 2.  CHECK == 0 means do not check overlay
!    properties.  CHECK == 1 means include an overlay only if PROP is an
!    element of the overlay's property list.  CHECK == 2 means include an
!    overlay only if PROP is an element of the overlay's property list and
!    its value equals VAL  .x
! */
  
  static int
! overlays_in (beg, end, extend, vec_ptr, len_ptr, next_ptr, prev_ptr, check, 
prop, value)
       int beg, end;
       int extend;
+      int check;
       Lisp_Object **vec_ptr;
+      Lisp_Object prop, value;
       int *len_ptr;
       int *next_ptr;
       int *prev_ptr;
***************
*** 2705,2710 ****
--- 2714,2725 ----
  
        XSETMISC (overlay, tail);
  
+       if ((check != 0)
+         && ((NILP (Fplist_member ((XOVERLAY (overlay)->plist), prop)))
+             || ((check == 2)
+                 && (!EQ ((Foverlay_get (overlay, prop)), value)))))
+       continue;
+ 
        ostart = OVERLAY_START (overlay);
        oend = OVERLAY_END (overlay);
        endpos = OVERLAY_POSITION (oend);
***************
*** 2753,2758 ****
--- 2768,2779 ----
  
        XSETMISC (overlay, tail);
  
+       if ((check != 0)
+         && ((NILP (Fplist_member ((XOVERLAY (overlay)->plist), prop)))
+             || ((check == 2)
+                 && (!EQ ((Foverlay_get (overlay, prop)), value)))))
+       continue;
+ 
        ostart = OVERLAY_START (overlay);
        oend = OVERLAY_END (overlay);
        startpos = OVERLAY_POSITION (ostart);
***************
*** 2814,2824 ****
  
    size = 10;
    v = (Lisp_Object *) alloca (size * sizeof *v);
!   n = overlays_in (start, end, 0, &v, &size, NULL, NULL);
    if (n > size)
      {
        v = (Lisp_Object *) alloca (n * sizeof *v);
!       overlays_in (start, end, 0, &v, &n, NULL, NULL);
      }
  
    for (i = 0; i < n; ++i)
--- 2835,2845 ----
  
    size = 10;
    v = (Lisp_Object *) alloca (size * sizeof *v);
!   n = overlays_in (start, end, 0, &v, &size, NULL, NULL, 0, Qnil, Qnil);
    if (n > size)
      {
        v = (Lisp_Object *) alloca (n * sizeof *v);
!       overlays_in (start, end, 0, &v, &n, NULL, NULL, 0, Qnil, Qnil);
      }
  
    for (i = 0; i < n; ++i)
***************
*** 3958,3971 ****
    return result;
  }
  
! DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 2, 0,
         doc: /* Return a list of the overlays that overlap the region BEG ... 
END.
  Overlap means that at least one character is contained within the overlay
  and also contained within the specified region.
  Empty overlays are included in the result if they are located at BEG
! or between BEG and END.  */)
!      (beg, end)
!      Lisp_Object beg, end;
  {
    int noverlays;
    Lisp_Object *overlay_vec;
--- 3979,4032 ----
    return result;
  }
  
! DEFUN ("overlays-in", Foverlays_in, Soverlays_in, 2, 3, 0,
         doc: /* Return a list of the overlays that overlap the region BEG ... 
END.
  Overlap means that at least one character is contained within the overlay
  and also contained within the specified region.
  Empty overlays are included in the result if they are located at BEG
! or between BEG and END.
! Optional argument PROP non-nil means return only overlays with property PROP. 
 */)
!      (beg, end, prop)
!      Lisp_Object beg, end, prop;
! {
!   int noverlays;
!   Lisp_Object *overlay_vec;
!   int len;
!   Lisp_Object result;
! 
!   CHECK_NUMBER_COERCE_MARKER (beg);
!   CHECK_NUMBER_COERCE_MARKER (end);
! 
!   len = 10;
!   overlay_vec = (Lisp_Object *) xmalloc (len * sizeof (Lisp_Object));
! 
!   /* Put all the overlays we want in a vector in overlay_vec.
!      Store the length in len.  */
!   if (NILP (prop))
!     noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
!                            (int *) 0, (int *) 0, 0, Qnil, Qnil);
!   else noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
!                               (int *) 0, (int *) 0, 1, prop, Qnil);
! 
!   /* Make a list of them all.  */
!   result = Flist (noverlays, overlay_vec);
! 
!   xfree (overlay_vec);
!   return result;
! }
! 
! DEFUN ("overlays-with-prop-eq-value",
!        Foverlays_with_prop_eq_value, Soverlays_with_prop_eq_value, 3, 4, 0,
!        doc: /* Return a list of overlays in BEG...END whose property PROP 
equals VALUE.
! An overlay is in BEG...END when at least one character within that
! region is contained within the overlay.  Empty overlays are included in
! the result if they are located at BEG or between BEG and END.
! An overlay is returned if and only if PROP is a member of the overlay's
! property list and the value of PROP is `eq' to VALUE.  If the optional
! argument VALUE is omitted return only overlays whose PROP has the value
! nil.  */)
!      (beg, end, prop, value)
!      Lisp_Object beg, end, prop, value;
  {
    int noverlays;
    Lisp_Object *overlay_vec;
***************
*** 3981,3987 ****
    /* Put all the overlays we want in a vector in overlay_vec.
       Store the length in len.  */
    noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
!                          (int *) 0, (int *) 0);
  
    /* Make a list of them all.  */
    result = Flist (noverlays, overlay_vec);
--- 4042,4048 ----
    /* Put all the overlays we want in a vector in overlay_vec.
       Store the length in len.  */
    noverlays = overlays_in (XINT (beg), XINT (end), 1, &overlay_vec, &len,
!                          (int *) 0, (int *) 0, 2, prop, value);
  
    /* Make a list of them all.  */
    result = Flist (noverlays, overlay_vec);
***************
*** 6142,6147 ****
--- 6203,6209 ----
    defsubr (&Soverlay_properties);
    defsubr (&Soverlays_at);
    defsubr (&Soverlays_in);
+   defsubr (&Soverlays_with_prop_eq_value);
    defsubr (&Snext_overlay_change);
    defsubr (&Sprevious_overlay_change);
    defsubr (&Soverlay_recenter);

reply via email to

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