|
1 | 1 | import * as vscode from "vscode"; |
2 | | -import type * as lc from "vscode-languageclient/node"; |
| 2 | +import * as lc from "vscode-languageclient/node"; |
3 | 3 | import * as ra from "./lsp_ext"; |
4 | 4 |
|
5 | 5 | import { Config, prepareVSCodeConfig } from "./config"; |
6 | 6 | import { createClient } from "./client"; |
7 | 7 | import { |
| 8 | + findRustToolchainFiles, |
8 | 9 | isCargoTomlEditor, |
9 | 10 | isDocumentInWorkspace, |
10 | 11 | isRustDocument, |
@@ -266,6 +267,17 @@ export class Ctx implements RustAnalyzerExtensionApi { |
266 | 267 | this.outputChannel!.show(); |
267 | 268 | }), |
268 | 269 | ); |
| 270 | + this.pushClientCleanup( |
| 271 | + this._client.onNotification( |
| 272 | + lc.ShowMessageNotification.type, |
| 273 | + async (params: lc.ShowMessageParams) => { |
| 274 | + // When an MSRV warning is detected and a rust-toolchain file exists, |
| 275 | + // show an additional message with actionable guidance about adding |
| 276 | + // the rust-analyzer component. |
| 277 | + await handleMsrvWarning(params.message); |
| 278 | + }, |
| 279 | + ), |
| 280 | + ); |
269 | 281 | } |
270 | 282 | return this._client; |
271 | 283 | } |
@@ -592,3 +604,43 @@ export interface Disposable { |
592 | 604 |
|
593 | 605 | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
594 | 606 | export type Cmd = (...args: any[]) => unknown; |
| 607 | + |
| 608 | +/** |
| 609 | + * Pattern to detect MSRV warning messages from the rust-analyzer server. |
| 610 | + */ |
| 611 | +const MSRV_WARNING_PATTERN = /using an outdated toolchain version.*rust-analyzer only supports/is; |
| 612 | + |
| 613 | +/** |
| 614 | + * Handles the MSRV warning by checking for rust-toolchain files and showing |
| 615 | + * an enhanced message if found. |
| 616 | + */ |
| 617 | +export async function handleMsrvWarning(message: string): Promise<boolean> { |
| 618 | + if (!MSRV_WARNING_PATTERN.test(message)) { |
| 619 | + return false; |
| 620 | + } |
| 621 | + |
| 622 | + const toolchainFiles = await findRustToolchainFiles(); |
| 623 | + if (toolchainFiles.length === 0) { |
| 624 | + return false; |
| 625 | + } |
| 626 | + |
| 627 | + const openFile = "Open rust-toolchain file"; |
| 628 | + const result = await vscode.window.showWarningMessage( |
| 629 | + "Your workspace uses a rust-toolchain file with a toolchain too old for the extension shipped rust-analyzer to work properly. " + |
| 630 | + "Consider adding the rust-analyzer component to the toolchain file to use a compatible rust-analyzer version. " + |
| 631 | + "Add the following to your rust-toolchain file's `[toolchain]` section:\n" + |
| 632 | + 'components = ["rust-analyzer"]', |
| 633 | + { modal: true }, |
| 634 | + openFile, |
| 635 | + ); |
| 636 | + |
| 637 | + if (result === openFile) { |
| 638 | + const fileToOpen = toolchainFiles[0]; |
| 639 | + if (fileToOpen) { |
| 640 | + const document = await vscode.workspace.openTextDocument(fileToOpen); |
| 641 | + await vscode.window.showTextDocument(document); |
| 642 | + } |
| 643 | + } |
| 644 | + |
| 645 | + return true; |
| 646 | +} |
0 commit comments