mzarnowski
mzarnowski

Reputation: 43

How to force the update of the code lenses in vscode

I am working on "run code" actions using code lenses in Metals (Scala Language Server). In our use case, we can provide those code lenses only once the compilation finishes. If the user is not modifying the source file during or after the compilation, vscode won't send a request for code lenses. This can lead to an ugly state of "stale code lenses" from before the compilation.

Digging into the internals of vscode-languageserver-node I have noticed that the CodeLensProvider can emit an onDidChangeCodeLenses event but it is not reflected in the LSP (https://github.com/microsoft/language-server-protocol/issues/192), hence I cannot send this event to vscode.

The other thing which would probably force reloading code lenses is the ICodeEditor::setModel method but I am not sure if this can be done directly from the vscode extension, since I cannot get a reference to the code editor.

How can this be done from either the Language Server or vscode extension? Or is there another, preferred way?

Upvotes: 4

Views: 1476

Answers (3)

Ross Bencina
Ross Bencina

Reputation: 4193

LSP 3.16 introduced a new request: workspace/codeLens/refresh and a new capability:

export interface CodeLensWorkspaceClientCapabilities {
    /**
     * Whether the client implementation supports a refresh request send from the server
     * to the client. This is useful if a server detects a change which requires a
     * re-calculation of all code lenses.
     */
    refreshSupport?: boolean;
}

You can read the whole patch and full documentation here: https://github.com/microsoft/language-server-protocol/commit/558f1e114a3dc53da7c3686a657ebef070275d63

I am able to request a refresh in a pygls-based language server using:

await ls.lsp.send_request_async(WORKSPACE_CODE_LENS_REFRESH)

In VSCode I have found that code lens refresh requests are not processed immediately. My experiments indicate that there needs to be a pause of ~400-500ms with no document edits before the code lens is updated.

Upvotes: 0

effeKtSVK
effeKtSVK

Reputation: 125

Two years later, it looks like there is still no implementation.

I managed to work around this by disposing of the codelens provider and immediately registering it again in my command (which is run by Codelens).

// NOTE: this is a hack to force the codelens to update
codelensDisposable.dispose();
codelensDisposable = vscode.languages.registerCodeLensProvider('*', codelensProvider);

EDIT: I just found out this appears to break GitLens extension, Codelens actions are missing when my extension is running as well...

Upvotes: 0

Gama11
Gama11

Reputation: 34138

Unfortunately, the language server protocol indeed doesn't support this yet. The corresponding feature request I opened a while ago can be found here.

I was able to work around this by implementing a dummy CodeLensProvider on the extension side for the same language ID (the VSCode API generally allows registering multiple providers for language features). It does nothing but call the onDidChangeCodeLenses event when necessary, the actual implementation is still on the language server side.

Upvotes: 1

Related Questions