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

From: Juri Linkov <[email-masked]>
Date: Fri, 27 Dec 2024 09:59:52 +0200

>> I can’t think of an counter example other than for_statment in
>> tree-sitter-c.
>
> Indeed, the 'for_statement' is a hard problem, and I see
> no good solution.

A possible solution would be to find a way to create "virtual" nodes.

This means transforming the existing syntax tree by inserting
addition nodes to it.  For example, transforming

   (for_statement "for" "("
    condition: (assignment_expression left: (identifier) operator: "=" right: (number_literal))
    ;
    body: (binary_expression left: (identifier) operator: "<" right: (number_literal))
    ;
    (update_expression operator: "++" argument: (identifier))
    ")"

into

   (for_statement "for"
    (for_parameters "("
     condition: (assignment_expression left: (identifier) operator: "=" right: (number_literal))
     ;
     body: (binary_expression left: (identifier) operator: "<" right: (number_literal))
     ;
     (update_expression operator: "++" argument: (identifier))
     ")"

by inserting the virtual node "for_parameters".  Not sure
if such transformation is supported by tree-sitter.

Generally, we have two problems with syntax trees created
by the authors of tree-sitter grammars:

1. Insufficient structure
2. Excessive structure

For insufficient structure a possible solution would be to insert
virtual nodes like above.  And for excessive structure we need
to flatten some nodes.  For example, in c-ts-mode:

  static -!-struct atimer *free_atimers;

'C-M-f' unexpectedly jumped not to the next symbol, but to

  static struct atimer-!- *free_atimers;

because of too much structure built in the syntax tree:

  (declaration
   type: (storage_class_specifier "static")
   declarator: (struct_specifier "struct" name: (type_identifier))
   (pointer_declarator "*" declarator: (identifier))
   ";")

So the solution could be to flatten 'struct_specifier' to move
'type_identifier' to be a sibling in the same list inside 'declaration':

  (declaration
   type: (storage_class_specifier "static")
   declarator: (struct_specifier "struct")
   (type_identifier)
   (pointer_declarator "*" declarator: (identifier))
   ";")

Also not sure if such thing is possible in tree-sitter.