Subject: Re: 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: Mon, 06 Jan 2025 15:19:35 -0500

> The problem is that ")" is not the final child of 'cast_expression'.
> So C-M-f/C-M-n can't stop after ")".
>
> All these problems stem from the imperfection of ts grammars.

I'm not sure if I'd call it "imperfection".  There are tradeoffs.

> It would be nice if someone will find a way to modify the grammars
> after importing them to Emacs core, to be able to insert more nodes.
> This will solve a whole class of problems.

I think some way to massage the parse tree would be useful (maybe by
massaging the grammar, but not necessarily).  The `cast_expression` is
one place where we could use it, but it would also help us deal with the
fact that grammars can change outside of our control and we may want our
major modes to support various versions of a grammar.

> Otherwise, if vendoring grammars is not feasible, an alternative
> would be to define a new treesit-thing like e.g. "paren" that
> will match anonymous nodes like:
>
>   (setq-local treesit-thing-settings
>               `((c
>                  (paren ,(rx (or "{" "}" "[" "]" "(" ")")))
>
> Then low-level treesit functions such as treesit-parent-until
> will have to check if there a preceding sibling that matches "paren"
> before using their real AST parent node.  This means maintaining
> a parallel virtual tree.

I'd prefer something more targeted, i.e. some way for the major mode to
add "extra rules" to explain that some part of `cast_expression` should
also be treated as a `list`.

        Stefan