Matching parentheses in a different node (CM/Lezer)

I’m writing a language server for a language where a flat version of the syntax is often syntax sugar for a nested version, for example (a,b) => c is (a) => (b) => c. For this reason it’s convenient to have rules like this:

Lambda {
    "(" Identifier lambdaRest
}

lambdaRest {
     ")" "=>" expression | LambdaMiddle
}

LambdaMiddle[@name="Lambda"]{
    "," Identifier lambdaRest
}

This produces a nice parse tree, but I noticed the parentheses aren’t getting highlighted in CodeMirror if there’s more than one variable. This doesn’t change by creating named nodes for parentheses with closedBy/openedBy. I figure this is because Lezer only matches parentheses in a single (capital letter) named node.

Is there a way to keep the weird rules and fix the matching? I think it would work for me to ignore lezer matching and use the default in CodeMirror, but I haven’t found a way to do that.

Not really. Several parts of the editor (see also selection by syntax node commands) assume that the syntax tree nodes correspond to the elements in the syntax as the programmer would see them.

So I’d recommend always having a node that corresponds to something like an argument list, and avoid wrapping the end of it in the way you’re doing. The changes to the grammar shouldn’t be too painful, at a glance.

1 Like

I didn’t know about syntax node commands, I was thinking of building them myself for the purpose of users being able to explore the typing rules applied to expressions. But that actually works perfectly with the weird grammar, e.g. expanding from the c in (a,b) => c we should look at the typing rule applied to b) => c.

The grammar code itself of course it could be anything, but since I’m using my lezer tree for compiling/language servering, it’s nice if the node structure and node.from/node.to match the semantics of the language. For example, when the cursor is after the , in (a,b) => c, I need to show that a is in context.

So I’d like to maintain that ignoring lezer parentheses matching would be useful for the specific weird thing I’m doing :slightly_smiling_face: