about summary refs log tree commit diff
path: root/editors/code/src
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-03-16 16:26:19 +0100
committerLukas Wirth <lukastw97@gmail.com>2023-03-16 16:26:19 +0100
commit66636939a63237fb7a6d1198dd9f92514807621e (patch)
tree6c014bbc33ffd5321206b598fd07623270babc15 /editors/code/src
parent8330f8efc6c79455d9217ba4a9cff16091ca8da5 (diff)
downloadrust-66636939a63237fb7a6d1198dd9f92514807621e.tar.gz
rust-66636939a63237fb7a6d1198dd9f92514807621e.zip
feat: Pop a notification prompting the user to add a Cargo.toml of unlinked file to the linkedProjects
Diffstat (limited to 'editors/code/src')
-rw-r--r--editors/code/src/client.ts74
-rw-r--r--editors/code/src/ctx.ts5
2 files changed, 68 insertions, 11 deletions
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 565cb9c6432..2a1c757dfef 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -8,6 +8,7 @@ import * as diagnostics from "./diagnostics";
 import { WorkspaceEdit } from "vscode";
 import { Config, prepareVSCodeConfig } from "./config";
 import { randomUUID } from "crypto";
+import { sep as pathSeparator } from "path";
 
 export interface Env {
     [name: string]: string;
@@ -69,7 +70,8 @@ export async function createClient(
     outputChannel: vscode.OutputChannel,
     initializationOptions: vscode.WorkspaceConfiguration,
     serverOptions: lc.ServerOptions,
-    config: Config
+    config: Config,
+    unlinkedFiles: vscode.Uri[]
 ): Promise<lc.LanguageClient> {
     const clientOptions: lc.LanguageClientOptions = {
         documentSelector: [{ scheme: "file", language: "rust" }],
@@ -119,6 +121,65 @@ export async function createClient(
                 const preview = config.previewRustcOutput;
                 const errorCode = config.useRustcErrorCode;
                 diagnosticList.forEach((diag, idx) => {
+                    let value =
+                        typeof diag.code === "string" || typeof diag.code === "number"
+                            ? diag.code
+                            : diag.code?.value;
+                    if (value === "unlinked-file" && !unlinkedFiles.includes(uri)) {
+                        let config = vscode.workspace.getConfiguration("rust-analyzer");
+                        if (config.get("showUnlinkedFileNotification")) {
+                            unlinkedFiles.push(uri);
+                            let folder = vscode.workspace.getWorkspaceFolder(uri)?.uri.fsPath;
+                            if (folder) {
+                                let parent_backslash = uri.fsPath.lastIndexOf(
+                                    pathSeparator + "src"
+                                );
+                                let parent = uri.fsPath.substring(0, parent_backslash);
+
+                                if (parent.startsWith(folder)) {
+                                    let path = vscode.Uri.file(
+                                        parent + pathSeparator + "Cargo.toml"
+                                    );
+                                    void vscode.workspace.fs.stat(path).then(() => {
+                                        vscode.window
+                                            .showInformationMessage(
+                                                `This rust file does not belong to a loaded cargo project. It looks like it might belong to the workspace at ${path}, do you want to add it to the linked Projects?`,
+                                                "Yes",
+                                                "No",
+                                                "Don't show this again"
+                                            )
+                                            .then((choice) => {
+                                                switch (choice) {
+                                                    case "Yes":
+                                                        break;
+                                                    case "No":
+                                                        config.update(
+                                                            "linkedProjects",
+                                                            config
+                                                                .get<any[]>("linkedProjects")
+                                                                ?.concat(
+                                                                    path.fsPath.substring(
+                                                                        folder!.length
+                                                                    )
+                                                                ),
+                                                            false
+                                                        );
+                                                        break;
+                                                    case "Don't show this again":
+                                                        config.update(
+                                                            "showUnlinkedFileNotification",
+                                                            false,
+                                                            false
+                                                        );
+                                                        break;
+                                                }
+                                            });
+                                    });
+                                }
+                            }
+                        }
+                    }
+
                     // Abuse the fact that VSCode leaks the LSP diagnostics data field through the
                     // Diagnostic class, if they ever break this we are out of luck and have to go
                     // back to the worst diagnostics experience ever:)
@@ -138,14 +199,6 @@ export async function createClient(
                                 .substring(0, index)
                                 .replace(/^ -->[^\n]+\n/m, "");
                         }
-                        let value;
-                        if (errorCode) {
-                            if (typeof diag.code === "string" || typeof diag.code === "number") {
-                                value = diag.code;
-                            } else {
-                                value = diag.code?.value;
-                            }
-                        }
                         diag.code = {
                             target: vscode.Uri.from({
                                 scheme: diagnostics.URI_SCHEME,
@@ -153,7 +206,8 @@ export async function createClient(
                                 fragment: uri.toString(),
                                 query: idx.toString(),
                             }),
-                            value: value ?? "Click for full compiler diagnostic",
+                            value:
+                                errorCode && value ? value : "Click for full compiler diagnostic",
                         };
                     }
                 });
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index c2dca733df8..5515921ed14 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -82,6 +82,7 @@ export class Ctx {
     private state: PersistentState;
     private commandFactories: Record<string, CommandFactory>;
     private commandDisposables: Disposable[];
+    private unlinkedFiles: vscode.Uri[];
 
     get client() {
         return this._client;
@@ -99,6 +100,7 @@ export class Ctx {
         this.clientSubscriptions = [];
         this.commandDisposables = [];
         this.commandFactories = commandFactories;
+        this.unlinkedFiles = [];
 
         this.state = new PersistentState(extCtx.globalState);
         this.config = new Config(extCtx);
@@ -218,7 +220,8 @@ export class Ctx {
                 this.outputChannel,
                 initializationOptions,
                 serverOptions,
-                this.config
+                this.config,
+                this.unlinkedFiles
             );
             this.pushClientCleanup(
                 this._client.onNotification(ra.serverStatus, (params) =>