Search code examples
javascriptnode.jsvisual-studio-codevscode-extensionslanguage-server-protocol

Vscode Language Client extension - how to send a message from the server to the client?


I have been developing a vscode extension that consits of client and server using the language server protocol.

At the moment, I am trying to do the following thing: when the server detects a certain condition, he requests the client to load a certain number of files into the workspace.

I am having serious problems doing this. Since the language server protocol does not have a specific request to do this I thought about sending a message from the server to the client and once the client detects this message he would proceed to execute this command.

The problem is, I also do not know how to do this. Can anyone please help me?


Solution

  • As long as you're sure the name doesn't collide with existing LSP methods, you can define arbitrary methods of your own. For instance, in the official lsp-sample, you could do this:

    (at the end of client/src/extension.ts)

    let client = new LanguageClient('lspSample', 'Language Server Example', serverOptions, clientOptions);
    client.onReady().then(() => {
        client.onNotification("custom/loadFiles", (files: Array<String>) => {
            console.log("loading files " + files);
        });
    });
    context.subscriptions.push(client.start());
    

    (in the documents.onDidChangeContent listener of server/src/server.ts)

    var files = ["path/to/file/a.txt", "path/to/file/b.txt"];
    connection.sendNotification("custom/loadFiles", [files]);
    

    This will output the following to the dev console whenever you change the contents of a .txt file (since the sample uses plaintext as its document selector):

    loading files path/to/file/a.txt,path/to/file/b.txt

    You pretty much have complete flexibility here when it comes to the names of custom methods, their parameters or when you invoke them. It's quite common for language servers to use custom methods like this that are not part of the protocol for various purposes (advanced functionality, internal debugging/development features, etc...).