Subject: Re: bug#58937: text-property-search-backward misses one-character regions
From: Eli Zaretskii <[email-masked]>
To: Nicolas Graner <[email-masked]>
Cc: [email-masked], [email-masked]
Date: Thu, 03 Nov 2022 11:35:40 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

> From: Nicolas Graner <[email-masked]>
> Cc: [email-masked], [email-masked]
> Date: Thu, 03 Nov 2022 00:40:43 +0100
> 
> This works fine in all the cases I have tested, although I don't claim
> to have tested all relevant combinations of arguments and region lengths
> and positions...

Thanks, I installed the change.

> Here, the PREDICATE argument is a function, not the usual t or nil:
> 
> (with-current-buffer (generate-new-buffer "test")
>   (insert "123456789")
>   (put-text-property 2 4 'foo "abcd")
>   (put-text-property 4 6 'foo "efgh")
>   (goto-char 1)
>   (text-property-search-forward 'foo 4 (lambda (l str) (= l (length str)))))

??? The documentation says PREDICATE is called with 2 arguments: the
VALUE argument to text-property-search-forward and the actual value of
the text property to examine.  There's no property value of 4 in this
example, so it sounds like you are (ab)using the feature in some way
that we didn't really intend to support.

More to the point, Emacs always considers segments of characters whose
values of the same property are different as distinct segments.  You
seem to expect that Emacs would join these two segments because you
supplied PREDICATE that returns t for both, but Emacs cannot do that,
because the underlying text-property machinery doesn't even look at
the next segment before it processes the first one.  And no PREDICATE
in this API can ever change that basic fact.

So your expectations are incorrect, and cannot be met by this API,
which specifically meant to examine the text segments one by one and
subject each one of them to PREDICATE, separately.

> The docstring for text-property-search-forward says:
>     If PREDICATE is nil (which is the default value), a value will
>     match if is not ‘equal’ to VALUE.  Furthermore, a nil PREDICATE
>     means that the match region is ended if the value changes.
> 
> This implies that when PREDICATE is not nil, the match region should not
> end when the value changes, but only when the predicate is no longer
> satisfied. Is this correct?

No, it isn't.  The region always ends where the property changes
value, regardless of what PREDICATE thinks.