Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable "Go to symbol" with a custom language in vscode?

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.

like image 480
nachocab Avatar asked Sep 04 '17 23:09

nachocab


1 Answers

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:

like image 159
Gama11 Avatar answered Oct 11 '22 10:10

Gama11