about summary refs log tree commit diff
path: root/editors/code/src
diff options
context:
space:
mode:
authorBruno Ortiz <brunortiz11@gmail.com>2023-04-05 14:57:01 -0300
committerBruno Ortiz <brunortiz11@gmail.com>2023-05-02 10:59:31 -0300
commit8e687f7afb156a7ad2458b7a5aa481b5d7e435d1 (patch)
tree5c2c855dd08623d1fef1db36593a4864d3d98164 /editors/code/src
parent1b8288ff966bcabadf8f15d71511ff96184e81ea (diff)
downloadrust-8e687f7afb156a7ad2458b7a5aa481b5d7e435d1.tar.gz
rust-8e687f7afb156a7ad2458b7a5aa481b5d7e435d1.zip
improving code to work with multi-workspaces
Diffstat (limited to 'editors/code/src')
-rw-r--r--editors/code/src/commands.ts70
-rw-r--r--editors/code/src/ctx.ts8
-rw-r--r--editors/code/src/dependencies_provider.ts6
-rw-r--r--editors/code/src/util.ts18
4 files changed, 84 insertions, 18 deletions
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index 7fe32754c90..4393d5fccbc 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -8,7 +8,15 @@ import { applySnippetWorkspaceEdit, applySnippetTextEdits } from "./snippets";
 import { spawnSync } from "child_process";
 import { RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
 import { AstInspector } from "./ast_inspector";
-import { isRustDocument, isCargoTomlDocument, sleep, isRustEditor, RustEditor } from "./util";
+import {
+    isRustDocument,
+    isCargoTomlDocument,
+    sleep,
+    isRustEditor,
+    RustEditor,
+    RustDocument,
+    closeDocument,
+} from "./util";
 import { startDebugSession, makeDebugConfig } from "./debug";
 import { LanguageClient } from "vscode-languageclient/node";
 import { LINKED_COMMANDS } from "./client";
@@ -269,27 +277,63 @@ export function openCargoToml(ctx: CtxInit): Cmd {
 
 export function revealDependency(ctx: CtxInit): Cmd {
     return async (editor: RustEditor) => {
-        const rootPath = vscode.workspace.workspaceFolders![0].uri.fsPath;
         const documentPath = editor.document.uri.fsPath;
-        if (documentPath.startsWith(rootPath)) return;
         const dep = ctx.dependencies?.getDependency(documentPath);
         if (dep) {
             await ctx.treeView?.reveal(dep, { select: true, expand: true });
         } else {
-            let documentPath = editor.document.uri.fsPath;
-            const parentChain: DependencyId[] = [{ id: documentPath.toLowerCase() }];
-            do {
-                documentPath = path.dirname(documentPath);
-                parentChain.push({ id: documentPath.toLowerCase() });
-            } while (!ctx.dependencies?.contains(documentPath));
-            parentChain.reverse();
-            for (const idx in parentChain) {
-                await ctx.treeView?.reveal(parentChain[idx], { select: true, expand: true });
-            }
+            await revealParentChain(editor.document, ctx);
         }
     };
 }
 
+/**
+ * This function calculates the parent chain of a given file until it reaches it crate root contained in ctx.dependencies.
+ * This is need because the TreeView is Lazy, so at first it only has the root dependencies: For example if we have the following crates:
+ * - core
+ * - alloc
+ * - std
+ *
+ * if I want to reveal alloc/src/str.rs, I have to:
+
+ * 1. reveal every children of alloc
+ * - core
+ * - alloc\
+ * &emsp;|-beches\
+ * &emsp;|-src\
+ * &emsp;|- ...
+ * - std
+ * 2. reveal every children of src:
+ * core
+ * alloc\
+ * &emsp;|-beches\
+ * &emsp;|-src\
+ * &emsp;&emsp;|- lib.rs\
+ * &emsp;&emsp;|- str.rs <------- FOUND IT!\
+ * &emsp;&emsp;|- ...\
+ * &emsp;|- ...\
+ * std
+ */
+async function revealParentChain(document: RustDocument, ctx: CtxInit) {
+    let documentPath = document.uri.fsPath;
+    const maxDepth = documentPath.split(path.sep).length - 1;
+    const parentChain: DependencyId[] = [{ id: documentPath.toLowerCase() }];
+    do {
+        documentPath = path.dirname(documentPath);
+        parentChain.push({ id: documentPath.toLowerCase() });
+        if (parentChain.length >= maxDepth) {
+            // this is an odd case that can happen when we change a crate version but we'd still have
+            // a open file referencing the old version
+            await closeDocument(document);
+            return;
+        }
+    } while (!ctx.dependencies?.contains(documentPath));
+    parentChain.reverse();
+    for (const idx in parentChain) {
+        await ctx.treeView?.reveal(parentChain[idx], { select: true, expand: true });
+    }
+}
+
 export async function execRevealDependency(e: RustEditor): Promise<void> {
     await vscode.commands.executeCommand("rust-analyzer.revealDependency", e);
 }
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index 69347522b86..dd2373d5847 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -7,6 +7,7 @@ import { Config, prepareVSCodeConfig } from "./config";
 import { createClient } from "./client";
 import {
     executeDiscoverProject,
+    isDocumentInWorkspace,
     isRustDocument,
     isRustEditor,
     LazyOutputChannel,
@@ -277,15 +278,16 @@ export class Ctx {
             ...this,
             client: client,
         };
-        const rootPath = vscode.workspace.workspaceFolders![0].uri.fsPath;
-        this._dependencies = new RustDependenciesProvider(rootPath, ctxInit);
+        this._dependencies = new RustDependenciesProvider(ctxInit);
         this._treeView = vscode.window.createTreeView("rustDependencies", {
             treeDataProvider: this._dependencies,
             showCollapseAll: true,
         });
 
+        this.pushExtCleanup(this._treeView);
         vscode.window.onDidChangeActiveTextEditor((e) => {
-            if (e && isRustEditor(e)) {
+            // we should skip documents that belong to the current workspace
+            if (e && isRustEditor(e) && !isDocumentInWorkspace(e.document)) {
                 execRevealDependency(e).catch((reason) => {
                     void vscode.window.showErrorMessage(`Dependency error: ${reason}`);
                 });
diff --git a/editors/code/src/dependencies_provider.ts b/editors/code/src/dependencies_provider.ts
index 2e5ea04922f..3edbb316814 100644
--- a/editors/code/src/dependencies_provider.ts
+++ b/editors/code/src/dependencies_provider.ts
@@ -15,7 +15,7 @@ export class RustDependenciesProvider
     dependenciesMap: { [id: string]: Dependency | DependencyFile };
     ctx: CtxInit;
 
-    constructor(private readonly workspaceRoot: string,ctx: CtxInit) {
+    constructor(ctx: CtxInit) {
         this.dependenciesMap = {};
         this.ctx = ctx;
     }
@@ -37,6 +37,7 @@ export class RustDependenciesProvider
     }
 
     refresh(): void {
+        this.dependenciesMap = {};
         this._onDidChangeTreeData.fire();
     }
 
@@ -56,7 +57,7 @@ export class RustDependenciesProvider
         element?: Dependency | DependencyFile
     ): vscode.ProviderResult<Dependency[] | DependencyFile[]> {
         return new Promise((resolve, _reject) => {
-            if (!this.workspaceRoot) {
+            if (!vscode.workspace.workspaceFolders) {
                 void vscode.window.showInformationMessage("No dependency in empty workspace");
                 return Promise.resolve([]);
             }
@@ -108,6 +109,7 @@ export class Dependency extends vscode.TreeItem {
         public readonly collapsibleState: vscode.TreeItemCollapsibleState
     ) {
         super(label, collapsibleState);
+        this.id = this.dependencyPath.toLowerCase();
         this.tooltip = `${this.label}-${this.version}`;
         this.description = this.version;
         this.resourceUri = vscode.Uri.file(dependencyPath);
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index 922fbcbcf35..0196b37b8b6 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -112,6 +112,24 @@ export function isRustEditor(editor: vscode.TextEditor): editor is RustEditor {
     return isRustDocument(editor.document);
 }
 
+export function isDocumentInWorkspace(document: RustDocument): boolean {
+    const workspaceFolders = vscode.workspace.workspaceFolders;
+    if (!workspaceFolders) {
+        return false;
+    }
+    for (const folder of workspaceFolders) {
+        if (document.uri.fsPath.startsWith(folder.uri.fsPath)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+export async function closeDocument(document: RustDocument) {
+    await vscode.window.showTextDocument(document, { preview: true, preserveFocus: false });
+    await vscode.commands.executeCommand("workbench.action.closeActiveEditor");
+}
+
 export function isValidExecutable(path: string): boolean {
     log.debug("Checking availability of a binary at", path);