Search code examples
javascriptparsingatom-editorparse-tree

Getting the entire tree-sitter parse tree inside an Atom package


I am attempting to write an Atom package which would require access to the parse tree generated internally for Atom by tree-sitter. I am unfamiliar with tree-sitter and not overly familiar with Atom packages.

While reading some tutorials for Atom packages in general, I came across a page which looks promising that discusses getting the "Scope descriptor for the given position in buffer coordinates" and on the same page a way to get the current grammar but nothing for getting the entire parse tree. Is this possible using the api provided by Atom's environment? If not how would I go about doing it otherwise? Maybe reparsing the tree from inside the package (though that sounds both more work than it's worth and inefficient)?


Solution

  • For anyone else who might need to do this in the future, Atom exposes atom.workspace which can be used to get various things such as the TextEditors, Grammars, etc. from the active environment. While tracing Atom's source, I found that the GrammarRegistry object which is accessible in the workspace (atom.workspace.grammarRegistry) has a method called languageModeForGrammarAndBuffer which returns a TreeSitterLanguageMode object which in turn has a getter for the tree (.tree). This method in turn needs a grammar and a textBuffer, both of which can be obtained from the workspace as well (the buffer can be gotten from the TextEditorRegistry). Putting that all together, to get the root node of the tree from an Atom package, you can use something like this:

    const grammarRegistry = atom.workspace.grammarRegistry;
    const grammar = grammarRegistry.treeSitterGrammarsById["source.js"]; // where source.js is the name of the tree-sitter grammar you want
    const buffer = atom.workspace.textEditorRegistry.editors.values().next().value.buffer; //assuming you want the first buffer
    const root = grammarRegistry.languageModeForGrammarAndBuffer(grammar, buffer).tree.rootNode;