From: martin rudalics <rudalics@gmx.at>
To: rms@gnu.org
Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org
Subject: Re: Feature request : Tab-completion for 'shell-comand'
Date: Fri, 14 Mar 2008 08:46:24 +0100 [thread overview]
Message-ID: <47DA2D50.5050101@gmx.at> (raw)
In-Reply-To: <E1Ja042-0007MZ-JZ@fencepost.gnu.org>
[-- Attachment #1: Type: text/plain, Size: 2285 bytes --]
> 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.
[-- Attachment #2: buffer.patch --]
[-- Type: text/plain, Size: 6549 bytes --]
*** 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);
next prev parent reply other threads:[~2008-03-14 7:46 UTC|newest]
Thread overview: 72+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-04 16:42 Feature request : Tab-completion for 'shell-comand' paul r
2008-03-04 21:54 ` Michael Albinus
2008-03-04 23:17 ` Juri Linkov
2008-03-05 1:55 ` Stefan Monnier
2008-03-06 8:40 ` TSUCHIYA Masatoshi
2008-03-06 10:04 ` Juri Linkov
2008-03-06 16:04 ` Stefan Monnier
2008-03-06 16:14 ` Drew Adams
2008-03-06 17:31 ` Miles Bader
2008-03-06 17:46 ` Drew Adams
2008-03-06 18:21 ` Stefan Monnier
2008-03-07 2:14 ` Miles Bader
2008-03-06 23:48 ` Juri Linkov
2008-03-06 17:48 ` Juri Linkov
2008-03-06 23:45 ` Juri Linkov
2008-03-06 23:47 ` Juri Linkov
2008-03-08 17:39 ` Richard Stallman
2008-03-08 22:21 ` Juri Linkov
2008-03-08 22:38 ` Lennart Borgman (gmail)
2008-03-08 22:57 ` Juri Linkov
2008-03-09 0:21 ` Lennart Borgman (gmail)
2008-03-08 23:27 ` Stefan Monnier
2008-03-09 16:39 ` Richard Stallman
2008-03-09 17:45 ` Juri Linkov
2008-03-10 6:12 ` Richard Stallman
2008-03-10 14:44 ` Cannot build the trunk since unicode (was: Feature request : Tab-completion for 'shell-comand') Stefan Monnier
2008-03-11 9:24 ` Richard Stallman
2008-03-11 9:40 ` Andreas Schwab
2008-03-10 22:35 ` Feature request : Tab-completion for 'shell-comand' Juri Linkov
2008-03-11 20:24 ` Richard Stallman
2008-03-12 0:31 ` Juri Linkov
2008-03-12 23:13 ` Johan Bockgård
2008-03-12 23:19 ` David Kastrup
2008-03-12 23:36 ` Johan Bockgård
2008-03-13 2:14 ` Juri Linkov
2008-03-13 9:28 ` Johan Bockgård
2008-03-13 14:54 ` Stefan Monnier
2008-03-13 19:02 ` martin rudalics
2008-03-14 2:54 ` Richard Stallman
2008-03-14 7:46 ` martin rudalics [this message]
2008-03-14 15:07 ` Stefan Monnier
2008-03-15 3:23 ` Richard Stallman
2008-03-15 3:24 ` Richard Stallman
2008-03-14 3:21 ` Stefan Monnier
2008-03-14 7:47 ` martin rudalics
2008-03-14 15:05 ` Stefan Monnier
2008-03-14 18:33 ` martin rudalics
2008-03-14 19:20 ` Stefan Monnier
2008-03-14 22:31 ` martin rudalics
2008-03-15 0:59 ` Stefan Monnier
2008-03-16 14:24 ` martin rudalics
2008-03-16 18:28 ` Stefan Monnier
2008-03-17 7:36 ` martin rudalics
2008-03-17 15:00 ` Stefan Monnier
2008-03-14 1:04 ` Juri Linkov
2008-03-09 14:01 ` TSUCHIYA Masatoshi
2008-03-09 17:48 ` Juri Linkov
2008-03-10 0:08 ` TSUCHIYA Masatoshi
2008-03-10 0:57 ` Drew Adams
2008-03-10 1:29 ` Juri Linkov
2008-03-10 2:20 ` Johan Bockgård
2008-03-10 2:37 ` Lennart Borgman (gmail)
2008-03-10 22:31 ` Juri Linkov
2008-03-12 1:31 ` TSUCHIYA Masatoshi
2008-03-12 2:12 ` Stefan Monnier
2008-03-12 10:42 ` Juri Linkov
2008-03-15 8:29 ` TSUCHIYA Masatoshi
2008-03-15 10:24 ` paul r
2008-03-15 21:35 ` Juri Linkov
2008-03-20 19:58 ` Stefan Monnier
2008-03-20 20:55 ` Juri Linkov
2008-03-21 17:17 ` 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=47DA2D50.5050101@gmx.at \
--to=rudalics@gmx.at \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
--cc=rms@gnu.org \
/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).