I have made a custom language extension and I would like to enable the "Go To Symbol" feature. I have tried to follow the guidelines here, but I'm still kind of lost.
I think all I need to do is implement a DocumentSymbolProvider
, but I'm not really sure how to go about it.
UPDATE
The example language server docs point to a repo that is deprecated. It is replaced with this one, which is much more complex. I think the simplest example I can find there is the lsp-sample, but it doesn't use a DocumentSymbolProvider
.
I've found other repos that do use symbol providers, but they are a bit overwhelming. I can't figure out what needs to go where (for example, do I need both a client and a server? Some packages only seem to use an extension.ts
without both client and server folders).
All I really want to do in my language is detect lines that start with @
and show them in the Go to Symbol pane. I'd love to see a simple tutorial of this.
Do I need both a client and a server?
Not necessarily. As the language support docs you linked show, there's usually two options: a "direct implementation" and one using the Language Server Protocol. For the former, you don't need a client / server architecture. Language Servers have the advantage of being editor-agnostic, you can theoretically use them in any editor that implements the protocol. A direct implementation is limited to usage in VSCode.
All I really want to do in my language is detect lines that start with
@
and show them in the Go to Symbol pane.
Here's the extension.ts
for a very simple example of a "direct implementation" for this:
'use strict';
import * as vscode from 'vscode';
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(
{language: "foo"}, new FooDocumentSymbolProvider()
));
}
class FooDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
public provideDocumentSymbols(document: vscode.TextDocument,
token: vscode.CancellationToken): Thenable<vscode.SymbolInformation[]> {
return new Promise((resolve, reject) => {
var symbols = [];
for (var i = 0; i < document.lineCount; i++) {
var line = document.lineAt(i);
if (line.text.startsWith("@")) {
symbols.push({
name: line.text.substr(1),
kind: vscode.SymbolKind.Field,
location: new vscode.Location(document.uri, line.range)
})
}
}
resolve(symbols);
});
}
}
You will also need to add this to the package.json
generated by the VSCode extension template. It registers the foo
language and activates the extension when a file with the .foo
extension is opened:
"activationEvents": [
"onLanguage:foo"
],
"contributes": {
"languages": [{
"id": "foo",
"extensions": [".foo"]
}]
}
Here it is in action:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With