What is TextEditor.symbolsForSelectedRanges() supposed to return?

Background: I’m trying to write an extension that adds two commands: “Expand selection” and “Shrink selection”. “Expand selection” should work similar to the corresponding functions in other editors (VS Code, Sublime Text) to expand the selection to the parent scope. For example, in the following code console.log('fo|o', bar); the cursor is positioned between the two o in foo. If I execute “Expand selection” the text foo should be selected, another invocation and 'foo' should be selected, next one would select 'foo', bar, and so on. “Shrink selection” works in the opposite direction.

However, currently I’m in the progress of learning the Nova APIs and I’m struggling with how TextEditor.symbolsForSelectedRanges() and TextEditor.symbolAtPosition() work.

This is my debug code so far:

exports.activate = function () {
  // Do work when the extension is activated
};

exports.deactivate = function () {
  // Clean up state before the extension is deactivated
};

nova.commands.register("modify-selection.expandSelection", (editor) => {
  editor.symbolsForSelectedRanges().forEach((symbol) => {
    console.log(
      "symbol",
      symbol.type,
      symbol.range,
      symbol.name,
      symbol.displayName
    );
  });
});

If I invoke the “Expand selection” command on this code, while having type (line 13) selected, the log shows:

symbol function [294, 294] undefined undefined

That is, it returns the console.log() function call as the closest symbol, but doesn’t even have the correct end of the range for the symbol.

Another example is selecting extension is activated (line 2) and invoking “Expand selection”.

symbol function [8, 27] activate activate

In this case the range has a start and end, but I would expect that the deepest displayable symbol (as the function is described in the docs) is actually the comment on line 2, not the function containing the comment.

Is this how the TextEditor.symbolsForSelectedRanges() and TextEditor.symbolAtPosition() are supposed to work? Am I missing something in the docs that would allow me to implement the commands I have described above?

Thank you.

Hello Florian,

The Symbols API only returns parts of the parse tree that are symbolicated (appear or contribute to the Symbols sidebar list). Comments are not symbolicated by most languages in any way, so they are not included in this tree. This is why your example returns the function that contains the comment at the cursor’s location on line 2.

For line 13, there is an anonymous symbol represented by the function passed to forEach, so that shows its name as undefined.

If you are looking for an API to let you introspect the entire parse tree, then there currently isn’t anything exposed. We can definitely consider this for a future update, however.

Thanks for your answer.

Just to make sure, the extension I want to implement is not possible with the current features of the API. Being able to introspect the entire parse tree would be awesome. Expanding and shrinking selections is one of the very few features of VS Code I’m missing since switching to Nova.