Subject: bug#73404: 30.0.50; [forward/kill/etc]-sexp commands do not behave as expected in tree-sitter modes

From: Stefan Monnier <[email-masked]>
Date: Sat, 11 Jan 2025 14:14:23 -0500

> While testing everything looked so nice when `C-M-f`
> and `C-M-b` moved on the whole key-value pairs.
>
> But in actual use, it turned out to be completely unusable.
>
> It feels this is because `C-M-f` is expected to move
> to the next symbol unless it's at the beginning
> of (...), [...], if...fi, begin...end.

Maybe this can be tuned?

Let's take a piece of Haskell code like:

    foo x y = do
        a <- readsomething
               x (bar y)
        b <- readsomethingelse
               x (baz y)
        return (a, b)

A) If the cursor is right before `a <- ...`, I definitely expect `C-M-f` to
   move just over the identifier.
B) If the cursor is right after `do` (i.e. looking-at EOL), I could see
   `C-M-f` moving either to the end of the `do` block (i.e. the end of the
   `foo` function, here), or to right after the closing paren of `(bar y)`.
C) If the cursor is right after the closing paren of `(bar y)`, then I'd
   expect `C-M-f` to move to the closing paren of `(baz y)`.

If we make the block/list syntax more explicit (which Haskell allows),
the above code is:

    foo x y = do{
        a <- readsomething
               x (bar y);
        b <- readsomethingelse
               x (baz y);
        return (a, b)
    }

In (A) it's clear we're already inside the block.

In (B), we have an ambiguity where the cursor can be considered to be
looking either at the whole {...} block, or just at the first statement
within it, but I think it's clearly not looking at just the `a` identifier.

In (C) what I propose is the behavior that SMIE uses in such cases.

        Stefan