eclipse-sprotty / sprotty-vscode

sprotty-vscode
Eclipse Public License 2.0
58 stars 24 forks source link

How to restart an LSP server? #33

Closed NicolasRouquette closed 1 year ago

NicolasRouquette commented 3 years ago

We have used this project to build a vscode extension for our language, see: https://github.com/opencaesar/oml-luxor

Sometimes, our XText-based LSP server gets confused; this can happen for example when someone is refactoring a lot of files at once, resulting in lots of errors. While one can sometimes recover by closing all tabs and opening files one at a time, this process can be tedious for novices. We would like to add a command to restart our LSP server, similar to what our NASA colleagues have done for the PVS VSCode extension, see: https://github.com/nasa/vscode-pvs/blob/master/vscode-pvs/docs/FAQ.md#q7-vscode-pvs-is-not-responding-and-reports-pvs-errors-what-can-i-do

There's been a related discussion in the Theia community about this: https://spectrum.chat/theia/dev/whats-a-graceful-way-to-restart-a-language-server~063cd65d-9dfb-498f-ba9b-8ef8a19140db

One suggestion involves calling LanguageClient.stop() and LanguageClient.start(). With SprottyLspVscodeExtension, it is currently not possible:

export abstract class SprottyLspVscodeExtension extends SprottyVscodeExtension {
    readonly languageClient: LanguageClient;

    protected acceptFromLanguageServerEmitter = new Emitter<ActionMessage>();

    constructor(extensionPrefix: string, context: vscode.ExtensionContext) {
        super(extensionPrefix, context);
        this.languageClient = this.activateLanguageClient(context);
        this.languageClient.onReady().then(() => {
            this.languageClient.onNotification(acceptMessageType, message => this.acceptFromLanguageServerEmitter.fire(message));
            this.languageClient.onNotification(openInTextEditorMessageType, message => this.openInTextEditor(message));
        });
    }

Since languageClient is read-only, we cannot do something like this:

this.languageClient.stop();
this.languageClient =  this.activateLanguageClient(context);
        this.languageClient.onReady().then(() => {
            this.languageClient.onNotification(acceptMessageType, message => this.acceptFromLanguageServerEmitter.fire(message));
            this.languageClient.onNotification(openInTextEditorMessageType, message => this.openInTextEditor(message));
        });

Would it make sense to allow somehow doing something like shown above?

Is there perhaps a different way to achieve the desired effect? For example, could we somehow force the extension to deactivate itself and re-activate itself?

spoenemann commented 1 year ago

Please check out v0.5.0, it brings a major redesign of the API.

You should also check out Langium as an alternative to Xtext for implementing language servers.