Subject: Re: bug#48317: 27.1; text-property-search-forward moves point to end when not found

From: Howard Melman <[email-masked]>
Date: Tue, 11 May 2021 15:28:48 -0400

On May 11, 2021, at 12:36 PM, Lars Ingebrigtsen <[email-masked]> wrote:
> 
> Howard Melman <[email-masked]> writes:
> 
>>> I'm sorry, I don't follow you.  It this still about
>>> 
>>> (text-property-search-forward 'facet 'foo)
>>> 
>>> ?  That works as designed, as far as I can tell.  (But not as documented
>>> in the Emacs 27.1 doc string.)
>> 
>> Yes, Note that says "facet" and not "face"
> 
> Yes, that the text property you're looking for is called `facet'?
> 
>> To be more clear, I find when calling:
>> 
>>  (text-property-search-forward 'unused-property 'my-package-face)
>> 
>> when no text in the buffer has the property unused-property, that
>> calling text-property-search-forward moves point to eob.
>> 
>> Is this intended behavior?  If so I don't understand why. 
> 
> I'm not sure I understand what you're not understanding.  :-)  

I have felt the same way :)  Thanks for your patience.

> You're using nil as the PREDICATE here (a missing parameter is nil), which
> means that you're searching for areas in the buffer where the text
> property `facet' is not equal to `foo'.  Which is the rest of the buffer.

Thank you for explaining the logic and not just saying "working as designed".
"Which is the rest of the buffer." is what clicked for me.

I was reading "text-property-search-forward" as "look forward to find
a text property PROPERTY with value VALUE."  There wasn't one, so the
search should should fail and not move point.  

To me, this function behaves unexpectedly different in these cases
(say in a font-locked elisp buffer just before the last defun):

    ;; a region with property face is found,
    ;; point is moved to the end of it
    (text-property-search-forward 'face)

    ;; a region with property unused is not found,
    ;; point is unmoved
    (text-property-search-forward 'unused)

    ;; a region with the specfied face is found,
    ;; point is moved to the beginning of it
    (text-property-search-forward 'face 'font-lock-function-name-face)

    ;; a region with the specfied face is not found,
    ;; point is moved to eob
    (text-property-search-forward 'face 'unused)

    ;; a region with the specfied property is not found,
    ;; point is moved to eob
    (text-property-search-forward 'unused-prop 'unused-value)

The first two behave perfectly reasonably to me.  And as the manual
suggests, behaves the same as search-forward.

The 3rd does as well, of course.

I'd expect both the 4th and the 5th to behave the same as the 2nd but
they move point to eob.

And while I now mostly understand (but don't fully grok) the logic,
it's baffling to me that to make the last three behave like the first
two I should set PREDICATE to t (and btw doing so changes the behavior
of the 3rd to leave point at the end of the match instead of the
beginning, which seems odd).

The difference between the 3rd and 4th isn't some subtle difference
between using equal and eq or something, it's that the specified value
of the face is not found as it was using the default predicate in the
3rd case.  And particularly in the 5th, the choice of predicate to
evaluate 'unused-value shouldn't come into play because 'unused-prop
itself isn't found.

And the documentation describing PREDICATE nil didn't help me at all.
In the manual it says for nil:

    (which means “not equal”)

which sounds to me as if it is using the function not.  

And in your updated docstring as:

    a value will match if is not `equal' to VALUE

which really throws me because the 3rd case above works and it's 
not "not `equal'" to font-lock-function-name-face!

Does this explain my confusion?

I interpret all of these:

    (search-forward "defun")
    (text-property-search-forward 'face)
    (text-property-search-forward 'face 'font-lock-function-name-face)

to mean search for the thing I specified, whether that's a string, a
specific property with any value or a specific property with a
specific value.  But somehow the last one is different. And try as I
might now to write how it's being interpreted I'm unable to. Search
for the property face but only if it is font-lock-function-name-face
or if it isn't...?

Howard