lezer-parser/lezer

Concise API for getting text of a node/token?

TedDriggs opened this issue · 2 comments

I'm trying to implement custom completions for a language which has Clause nodes whose definition is:

Clause { Property Operator Operand }

Appropriate completions for each property depend on looking up the value in the preceding elements; once the user has entered a property name, I look that up and discover it's a string, and therefore the list of operators available for completion are =, !=, startswith etc.

Oddly enough, the most cumbersome/verbose piece is getting the text of each node so I can do that lookup. The closest API I've found to what I need is EditorState.sliceDoc, which works, but I have to separate the from and the to values into two arguments when calling that, which gets clunky:

const clause: { property?: string; operator?: string; operand?: string } = {
        property: clauseWithNodes?.property
            ? state.sliceDoc(
                  clauseWithNodes.property.from,
                  clauseWithNodes.property.to,
              )
            : undefined,
        operator: clauseWithNodes?.operator
            ? state.sliceDoc(
                  clauseWithNodes.operator.from,
                  clauseWithNodes.operator.to,
              )
            : undefined,
        operand: clauseWithNodes?.operand
            ? state.sliceDoc(
                  clauseWithNodes.operand.from,
                  clauseWithNodes.operand.to,
              )
            : undefined,
    };

Is there a more concise way that I'm missing to ask for the text of a given SyntaxNode?

No. The tree doesn't have access to the document text, so it can't provide a getter or something for this. You could write a helper function tokenText = node => state.sliceDoc(node.from, node.to) to simplify this code, I guess.