Reputation: 25601
I'm working in a language that usually has very large and hard to navigate files, so I would like to readily see what function I'm in at all times, since that's usually the biggest annoyance (paging up ~20 times to find the current function name, then paging back down).
I see how I can write an extension to list all the functions by registering a document symbol provider. Before I go too far down path, though, I want to know if there will be some way to automatically and constantly have some sort of indication in the outline view of which node represents the current position in the code editor. If not, I may just have to create my own tree view instead (will that have this capability?).
Upvotes: 4
Views: 2373
Reputation: 25601
If you have a reasonably functional outline view, that is to say, one that has the symbols hierarchically arranged by providing range objects for the full scope of each symbol instead of just a position, then you can toggle the "Breadcrumbs" item in the view menu to have a constant view of where you are within the outline's hierarchy. This is exactly what I was after.
To help with this, I had some data stored in a variable called currentBlock
, including symbolInformation
that was created when I encountered the first line of, for example, a method (taken from a match object returned from a regular expression):
currentBlock.symbolInformation = new vscode.SymbolInformation(
match[1],
vscode.SymbolKind.Method,
className,
new vscode.Location(document.uri,
new vscode.Position(lineNum, line.firstNonWhitespaceCharacterIndex)));
Then when I got to the end of the block I would wrap up the remainder of the information incorporating the data stored earlier, and push it onto the SymbolInformation[]
result.
private popBlock(document: vscode.TextDocument, lineNum: number, currentBlock: IndentInfo): vscode.SymbolInformation | undefined {
if (currentBlock.symbolInformation !== undefined) {
currentBlock.symbolInformation = new vscode.SymbolInformation(
currentBlock.symbolInformation.name,
currentBlock.symbolInformation.kind,
currentBlock.symbolInformation.containerName,
new vscode.Location(
currentBlock.symbolInformation.location.uri,
new vscode.Range(
currentBlock.symbolInformation.location.range.start,
new vscode.Position(lineNum-1, document.lineAt(lineNum-1).text.length)
)
)
);
return currentBlock.symbolInformation;
}
}
Here you can see the breadcrumbs reporting the full context of the current location above the editor pane. It's based on the same information that is used to build the outline.
Upvotes: 1
Reputation: 53307
Yes, this is possible. Your tree provider needs a way to match a symbol to a tree item, then call TreeView.reveal()
. Here's code I use to select an entry in a list of actions, depending on where the caret is in the current source editor:
public update(editor: TextEditor) {
let position = editor.selection.active;
let action = Utils.findInListFromPosition(this.actions, position.character, position.line + 1);
if (action) {
this.actionTree.reveal(action, { select: true });
return;
}
let predicate = Utils.findInListFromPosition(this.predicates, position.character, position.line + 1);
if (predicate) {
this.actionTree.reveal(predicate, { select: true });
return;
}
}
This method is called from the selection change event registered in the main extension file:
window.onDidChangeTextEditorSelection((event: TextEditorSelectionChangeEvent) => {
if (event.textEditor.document.languageId === "antlr" && event.textEditor.document.uri.scheme === "file") {
...
actionsProvider.update(event.textEditor);
}
});
Upvotes: 1