Subject: RE: bug#33167: 26; Doc string of `region-extract-function'

From: Drew Adams <[email-masked]>
Date: Sat, 27 Oct 2018 12:02:55 -0700 (PDT)

> > > > 1. What are the BEG and END args passed to `filter-buffer-
> > > >    substring'?
> > > >    Is BEG the smallest car of any of the zones in the
> > > >    noncontiguous
> > > >    region, and END the largest cdr of any of the zones?
> > >
> > > They are the first and the last positions of the region for
> > > filter-buffer-substring to act upon.  That function is not supposed
> to
> > > process non-contiguous regions.
> >
> > Yes, but where do they come from, for that call?  How do they
> > relate to, or how are they derived from, the noncontiguous
> > region? Are they point and mark?  Something else?  That's the
> > question.
> 
> It's entirely up to the region-extract-function that handles such
> regions.  The default one doesn't.  So I don't see why these questions
> need to be answered in the doc string of filter-buffer-substring, they
> don't belong there and would only confuse.

OK.  I guess you're saying that the `region-extract-function'
must invoke `filter-buffer-substring' on the content of each
piece of the noncontiguous region, but it can pass whatever
BEG and END positions it wants, to `filter-buffer-substring'.
There is no specified relation between those values it passes
and the BEG and END of each piece.

That makes little sense to me, so far.

I see that in the rectangle case it does decide what BEG and
END values to use, and these do not necessarily correspond to
the limits of the pieces.

In any case, that the use of the var for rectangles might
filter each line of the region in the way that it does says
nothing about what another value of the variable, in some
other context might do.

But if the spec of the variable imposes nothing on the BEG
and END values passed for filtering, then why does it impose
a requirement that `filter-buffer-substring' must be called?

The doc string of `region-extract-function' says that it
returns the content of the region as a string, after
filtering with `filter-buffer-substring' (in the "anything
else" case).

(You have presumably corrected that to say that it returns
a list of such strings - after each is filtered.)

If everything were up to the function that is the value of
`region-extract-function' then there would be no need, and
it would be incorrect, to state that it must filter buffer
content by calling `filter-buffer-substring'.

If, however, it is a _requirement_ that it calls
`filter-buffer-substring' then we need to know what args
it passes for BEG and END, in addition to knowing that it
needs to pass METHOD as the 3rd arg.

Otherwise, the need to use `filter-buffer-substring' is
a hollow requirement (no requirement at all).  If there is
no limit on what it can pass as BEG and END then I do not
see why we say that it must call `filter-buffer-substring'.
Whether it calls that function or not, it can, it seems,
do anything it likes, as long as it returns, for each
piece, some subsequence of that piece.

Worse: If there is no requirement on what it can pass
as BEG and END - not necessarily any relation between
those args passed and the limits of the pieces of the
noncontiguous region, then it can return any list of
subsequences of the buffer - not necessarily related
to the noncontiguous region at all.

I truly do not understand the intended (specified)
behavior of a function that can be the value of this
variable.  It's not enough to look at the rectangle
example - that doesn't specify what, in general, can
and cannot be a legitimate value of the variable.

My impression, so far, is that the actual requirement
for the function (definition of a proper value for the
variable),for the "anything else" case, is just that
the strings in the returned list must be subsequences
of the pieces of the noncontiguous region.

> > Not sure what you're saying.
> 
> You say that passing the 3rd arg is "useless", and
> I don't understand why.

I said:

 The 3rd arg to `filter-buffer-substring' just deletes the
 region from BEG to END if it is non-nil, so it seems like
 passing that non-nil 3rd arg is useless, as the region
 gets deleted anyway, by `region-extract-function'.

In the "anything else" case the `region-extract-function'
must delete the region - the whole noncontiguous region.
How it does that is its business presumably.

Since it deletes the whole noncontig region anyway, why
must it also pass METHOD to `filter-buffer-substring'?
The only reason to pass a non-nil value as 3rd arg is to
delete the text between the first two args passed.

But see above.  You've now said, IIUC, that it can pass
_any_ BEG and END values to `filter-buffer-substring' -
those values need not have anything to do with the region
or its pieces.  So is the point of passing METHOD to
`filter-buffer-substring' to be able to delete additional
text, which is not in the (noncontiguous) region?  What's
it about?

> > What are BEG and END that get passed to it?
> 
> The doc string already tells that: the beginning and
> the end of the region to be filtered.

No, the doc string says nothing about the BEG and END
values that get passed to `filter-buffer-substring'.
And you pointed out that those values passed need not
have any relation to the BEG and END limits of the pieces
of the noncontiguous region.  And it's certainly true,
e.g. for rectangles, that they need not be _equal_ to
the piece limits.

>>>> Or is what happens perhaps that EACH element of
>>>> the noncontiguous region, that is, each zone
>>>> (BEG<N> . END<N>) of the list ((BEG1 . END1) ...)
>>>> gets filtered by `filter-buffer-substring', passing
>>>> its BEG END and METHOD
> > >
> > > Yes!
> >
> > Then please say that in the doc.
> 
> NO!  Because that's just one possible implementation,
> for one possible kind of non-contiguous regions.

I didn't ask about one possible kind.  I asked if
that's what happens for any noncontiguous region.
You replied "Yes!", so I requested that that info be
added to the doc.

Now, and above IIUC, you've said that it's not true
for all non-contig regions.  From what you've said
above, it can pass _any_ BEG and END values it wants
for any given piece of the noncontig region.

But at least the doc can say, and it does now say,
that `filter-buffer-substring' is called once for
each piece.  What it does not say is that it need
not be called with the limits of that piece - it
can be called with any two buffer positions
(apparently).

I find it hard to believe that we would both (1)
insist that the function (in the "anything else"
case) must call `filter-buffer-substring' and
(2) not specify some required relation between the
limits passed to `filter-buffer-substring' and the
limits of the region piece.

That's what I've understood now, from your last
message.  Would you please confirm or correct that
understanding of what you've said?

I can see that the function should iterate over
the pieces of the region.  I can see that it might
be good to let it remove some bits of those pieces,
i.e., filter them a la `filter-buffer-substring'.

I guess I can even imagine that it might even be
useful for a function to return subsequences of the
buffer text that have no relation to the pieces of
the noncontiguous region, but that's a stretch.

But in that last case, I see no reason to impose
the use of `filter-buffer-substring' to accomplish
that.

And in any case, once the spec says that the
function (in the "anything else" case) must delete
the noncontiguous region, I see no reason why the
function must pass METHOD to `filter-buffer-substring',
unless you really want to allow the function to delete
not only the noncontiguous region but also any other
text in the buffer.

I'm trying to understand what the requirement is
for a function that is the value of
`region-extract-function'.

Confirming that it iterates over the pieces of
a noncontiguous region cleared up one problem.
But the use by `region-extract-function' of
`filter-buffer-substring' is less clear than ever,
I'm afraid.