Subject: bug#9300: 24.0.50; `bounds-of-thing-at-point' does not return nil when just after THING

From: Drew Adams <[email-masked]>
Date: Fri, 26 Feb 2016 06:39:32 -0800 (PST)

> > But the proper fix for 3rd-party code, mentioned above, does not
> > have any such problem.  It should look for a thing at (1- (point))
> > if it wants to get a thing that might be just before point but not
> > at point.
> 
> If the thing _begins_ at point, and the third-party code in question
> calls (save-excursion (forward-char -1) (thing-at-point 'foo)), they
> will get nil.

So what?  The point is that if code wants to get a thing at point
OR a thing at point-minus-one, then that's exactly what it should
check - which is, BTW, what the currently bugged code does.

> > You're the one who
> > mentioned that your code depends on checking for a thing at the
> > wrong position in order to get a thing at point-minus-one.  And
> > you mentioned an Eclipse function that acts similarly.  That's
> > two.
> 
> I never mentioned anything Eclipse-related in this bug.

Sorry - "eclim".

> >>> if they really want the bugged behavior.  Better: tell them
> >>> to use the fixed `bounds-of-thing-at-point' after backing up
> >>> so point is actually on the THING instead of after it.
> >>
> >> Any such client would be forced to call bounds-of-thing-at-point-
> >> strict twice. Which is not particularly ideal.
> >
> > Not at all.  Why do you say that?
> 
> See above.

No.  Just use the current (bugged) implementation.  It is a
`bounds-of-thing-at-point-or-at-point-minus-one'.

You might even provide a function that takes an other (e.g.
optional) arg that is the other end of a range of positions
over which to check whether there is a thing.

Currently, you want the behavior of getting a thing at point or
a thing that is point-minus-one.  Add an argument to the new
function that lets it return a thing that is at any of the positions
between point and the new arg (a position).

I only need to test for (and get) the thing at point (really at
point).  But other use cases might want what you want.

> >> Think of the semantics of `match-end', or the last argument of
> >> `substring'.
> >
> > Think of all the other uses of thing-at-point, and the other
> > THINGs it finds and where it finds them.
> >
> > Type (foo bar) at top level, and put point after the ).
> > M-: (thing-at-point 'list)
> > What do you get?  id it give you "(foo bar)"?  Or did it give
> > you nil?  There is no list at point.  Is this a bug?  No; it's
> > TRT.
> 
> If the list is at the end of the buffer, it gives me an empty
> string, or a string of spaces. So yeah, this particular "thing"
> seems bugged.

I have much better-behaving list-at-point code.  It's in the
same file, if you are really interested.  It always returns nil
if the cursor is not on a list (there is no list at point),
including when point is at eob.

The crucial point is that THINGs that end *before* point are not
*at* point.  That's all.  And this applies to all kinds of THINGs.

Whether or not there are bugs for particular kinds of THINGs is
something else, and those should be fixed individually.  Comments
come to mind, IIRC.  I have several such fixes in my code.

But the basic off-by-one bug (this bug) needs to be fixed,
if we expect coherent thing-at-point behavior and flexible,
repeatable use.

> > Why don't you present a valid (in your sense) configuration
> >> that a bounds-of-thing-at-point implementation without the
> >> "else" branch will return nil in?
> >
> > OK, I give up.
> 
> Because there is no such example.

Sigh.

> > It's clearly not about your being unconvinced that the fix is
> > correct.  It's about your not wanting to give up your ingrained
> > expectations of the incorrect behavior.
> 
> Not just mine. I believe I have demonstrated that the code has been
> written with exactly this expectation in mind. And stayed like that
> for decades.