about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/editors/code
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-12-12 12:24:31 +0100
committerRalf Jung <post@ralfj.de>2024-12-12 12:24:31 +0100
commitf590fa92140b5cc375bd4bc16ca6e930c5bf9e33 (patch)
tree47d0fb5e03dc56be5e33f9b84f668b540b990e31 /src/tools/rust-analyzer/editors/code
parentcc797a2b741be734289ba857e99dc72be908d92d (diff)
parenta4ef751e26a90dd3b6b35fdbfef1e4854f9d80e1 (diff)
downloadrust-f590fa92140b5cc375bd4bc16ca6e930c5bf9e33.tar.gz
rust-f590fa92140b5cc375bd4bc16ca6e930c5bf9e33.zip
Merge from rustc
Diffstat (limited to 'src/tools/rust-analyzer/editors/code')
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json46
-rw-r--r--src/tools/rust-analyzer/editors/code/src/client.ts2
-rw-r--r--src/tools/rust-analyzer/editors/code/src/config.ts31
-rw-r--r--src/tools/rust-analyzer/editors/code/src/ctx.ts18
-rw-r--r--src/tools/rust-analyzer/editors/code/src/debug.ts12
-rw-r--r--src/tools/rust-analyzer/editors/code/src/run.ts35
-rw-r--r--src/tools/rust-analyzer/editors/code/tests/unit/runnable_env.test.ts122
7 files changed, 106 insertions, 160 deletions
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 82c43b76fdd..469c1b458d5 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -425,6 +425,41 @@
                         ],
                         "default": "openLogs",
                         "markdownDescription": "Action to run when clicking the extension status bar item."
+                    },
+                    "rust-analyzer.statusBar.documentSelector": {
+                        "type": [
+                            "array",
+                            "null"
+                        ],
+                        "items": {
+                            "type": "object",
+                            "properties": {
+                                "language": {
+                                    "type": [
+                                        "string",
+                                        "null"
+                                    ]
+                                },
+                                "pattern": {
+                                    "type": [
+                                        "string",
+                                        "null"
+                                    ]
+                                }
+                            }
+                        },
+                        "default": [
+                            {
+                                "language": "rust"
+                            },
+                            {
+                                "pattern": "**/Cargo.toml"
+                            },
+                            {
+                                "pattern": "**/Cargo.lock"
+                            }
+                        ],
+                        "markdownDescription": "Determines when to show the extension status bar item based on the currently open file. Use `{ \"pattern\": \"**\" }` to always show. Use `null` to never show."
                     }
                 }
             },
@@ -2570,10 +2605,13 @@
             {
                 "title": "typing",
                 "properties": {
-                    "rust-analyzer.typing.autoClosingAngleBrackets.enable": {
-                        "markdownDescription": "Whether to insert closing angle brackets when typing an opening angle bracket of a generic argument list.",
-                        "default": false,
-                        "type": "boolean"
+                    "rust-analyzer.typing.excludeChars": {
+                        "markdownDescription": "Specify the characters to exclude from triggering typing assists. The default trigger characters are `.`, `=`, `<`, `>`, `{`, and `(`.",
+                        "default": "|<",
+                        "type": [
+                            "null",
+                            "string"
+                        ]
                     }
                 }
             },
diff --git a/src/tools/rust-analyzer/editors/code/src/client.ts b/src/tools/rust-analyzer/editors/code/src/client.ts
index eac7b849fdb..4ce19f5c665 100644
--- a/src/tools/rust-analyzer/editors/code/src/client.ts
+++ b/src/tools/rust-analyzer/editors/code/src/client.ts
@@ -324,7 +324,7 @@ class ExperimentalFeatures implements lc.StaticFeature {
     }
     fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
         capabilities.experimental = {
-            snippetTextEdit: true,
+            snippetTextEdit: false,
             codeActionGroup: true,
             hoverActions: true,
             serverStatusNotification: true,
diff --git a/src/tools/rust-analyzer/editors/code/src/config.ts b/src/tools/rust-analyzer/editors/code/src/config.ts
index 67bc72f1e12..f7ef80df2ba 100644
--- a/src/tools/rust-analyzer/editors/code/src/config.ts
+++ b/src/tools/rust-analyzer/editors/code/src/config.ts
@@ -261,9 +261,9 @@ export class Config {
         return this.get<boolean | undefined>("testExplorer");
     }
 
-    get runnablesExtraEnv() {
+    runnablesExtraEnv(label: string): Record<string, string> | undefined {
         const item = this.get<any>("runnables.extraEnv") ?? this.get<any>("runnableEnv");
-        if (!item) return item;
+        if (!item) return undefined;
         const fixRecord = (r: Record<string, any>) => {
             for (const key in r) {
                 if (typeof r[key] !== "string") {
@@ -271,11 +271,28 @@ export class Config {
                 }
             }
         };
+
+        const platform = process.platform;
+        const checkPlatform = (it: RunnableEnvCfgItem) => {
+            if (it.platform) {
+                const platforms = Array.isArray(it.platform) ? it.platform : [it.platform];
+                return platforms.indexOf(platform) >= 0;
+            }
+            return true;
+        };
+
         if (item instanceof Array) {
-            item.forEach((x) => fixRecord(x.env));
-        } else {
-            fixRecord(item);
+            const env = {};
+            for (const it of item) {
+                const masked = !it.mask || new RegExp(it.mask).test(label);
+                if (masked && checkPlatform(it)) {
+                    Object.assign(env, it.env);
+                }
+            }
+            fixRecord(env);
+            return env;
         }
+        fixRecord(item);
         return item;
     }
 
@@ -331,6 +348,10 @@ export class Config {
         return this.get<string>("statusBar.clickAction");
     }
 
+    get statusBarDocumentSelector() {
+        return this.get<vscode.DocumentSelector>("statusBar.documentSelector");
+    }
+
     get initializeStopped() {
         return this.get<boolean>("initializeStopped");
     }
diff --git a/src/tools/rust-analyzer/editors/code/src/ctx.ts b/src/tools/rust-analyzer/editors/code/src/ctx.ts
index 234fe6ab024..4a3f66b00d0 100644
--- a/src/tools/rust-analyzer/editors/code/src/ctx.ts
+++ b/src/tools/rust-analyzer/editors/code/src/ctx.ts
@@ -88,6 +88,7 @@ export class Ctx implements RustAnalyzerExtensionApi {
     private _treeView: vscode.TreeView<Dependency | DependencyFile | DependencyId> | undefined;
     private lastStatus: ServerStatusParams | { health: "stopped" } = { health: "stopped" };
     private _serverVersion: string;
+    private statusBarActiveEditorListener: Disposable;
 
     get serverPath(): string | undefined {
         return this._serverPath;
@@ -119,6 +120,10 @@ export class Ctx implements RustAnalyzerExtensionApi {
         this._serverVersion = "<not running>";
         this.config = new Config(extCtx.subscriptions);
         this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
+        this.updateStatusBarVisibility(vscode.window.activeTextEditor);
+        this.statusBarActiveEditorListener = vscode.window.onDidChangeActiveTextEditor((editor) =>
+            this.updateStatusBarVisibility(editor),
+        );
         if (this.config.testExplorer) {
             this.testController = vscode.tests.createTestController(
                 "rustAnalyzerTestController",
@@ -141,6 +146,7 @@ export class Ctx implements RustAnalyzerExtensionApi {
     dispose() {
         this.config.dispose();
         this.statusBar.dispose();
+        this.statusBarActiveEditorListener.dispose();
         this.testController?.dispose();
         void this.disposeClient();
         this.commandDisposables.forEach((disposable) => disposable.dispose());
@@ -404,7 +410,6 @@ export class Ctx implements RustAnalyzerExtensionApi {
         let icon = "";
         const status = this.lastStatus;
         const statusBar = this.statusBar;
-        statusBar.show();
         statusBar.tooltip = new vscode.MarkdownString("", true);
         statusBar.tooltip.isTrusted = true;
         switch (status.health) {
@@ -472,6 +477,17 @@ export class Ctx implements RustAnalyzerExtensionApi {
         statusBar.text = `${icon}rust-analyzer`;
     }
 
+    private updateStatusBarVisibility(editor: vscode.TextEditor | undefined) {
+        const documentSelector = this.config.statusBarDocumentSelector;
+        if (documentSelector != null) {
+            if (editor != null && vscode.languages.match(documentSelector, editor.document) > 0) {
+                this.statusBar.show();
+                return;
+            }
+        }
+        this.statusBar.hide();
+    }
+
     pushExtCleanup(d: Disposable) {
         this.extCtx.subscriptions.push(d);
     }
diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts
index 9e2e3d2185b..f21ca2e8f96 100644
--- a/src/tools/rust-analyzer/editors/code/src/debug.ts
+++ b/src/tools/rust-analyzer/editors/code/src/debug.ts
@@ -148,8 +148,16 @@ async function getDebugConfiguration(
         return path.normalize(p).replace(wsFolder, `\${workspaceFolder${workspaceQualifier}}`);
     }
 
-    const env = prepareEnv(inheritEnv, runnable.label, runnableArgs, config.runnablesExtraEnv);
-    const executable = await getDebugExecutable(runnableArgs, env);
+    const executable = await getDebugExecutable(
+        runnableArgs,
+        prepareEnv(true, {}, config.runnablesExtraEnv(runnable.label)),
+    );
+
+    const env = prepareEnv(
+        inheritEnv,
+        runnableArgs.environment,
+        config.runnablesExtraEnv(runnable.label),
+    );
     let sourceFileMap = debugOptions.sourceFileMap;
 
     if (sourceFileMap === "auto") {
diff --git a/src/tools/rust-analyzer/editors/code/src/run.ts b/src/tools/rust-analyzer/editors/code/src/run.ts
index 8a82a5a58cf..f71ab7ffbd8 100644
--- a/src/tools/rust-analyzer/editors/code/src/run.ts
+++ b/src/tools/rust-analyzer/editors/code/src/run.ts
@@ -5,7 +5,7 @@ import * as tasks from "./tasks";
 
 import type { CtxInit } from "./ctx";
 import { makeDebugConfig } from "./debug";
-import type { Config, RunnableEnvCfg, RunnableEnvCfgItem } from "./config";
+import type { Config } from "./config";
 import type { LanguageClient } from "vscode-languageclient/node";
 import { unwrapUndefinable, type RustEditor } from "./util";
 
@@ -81,32 +81,13 @@ export function prepareBaseEnv(
 
 export function prepareEnv(
     inheritEnv: boolean,
-    label: string,
-    runnableArgs: ra.CargoRunnableArgs,
-    runnableEnvCfg?: RunnableEnvCfg,
+    runnableEnv?: Record<string, string>,
+    runnableEnvCfg?: Record<string, string>,
 ): Record<string, string> {
-    const env = prepareBaseEnv(inheritEnv, runnableArgs.environment);
-    const platform = process.platform;
-
-    const checkPlatform = (it: RunnableEnvCfgItem) => {
-        if (it.platform) {
-            const platforms = Array.isArray(it.platform) ? it.platform : [it.platform];
-            return platforms.indexOf(platform) >= 0;
-        }
-        return true;
-    };
+    const env = prepareBaseEnv(inheritEnv, runnableEnv);
 
     if (runnableEnvCfg) {
-        if (Array.isArray(runnableEnvCfg)) {
-            for (const it of runnableEnvCfg) {
-                const masked = !it.mask || new RegExp(it.mask).test(label);
-                if (masked && checkPlatform(it)) {
-                    Object.assign(env, it.env);
-                }
-            }
-        } else {
-            Object.assign(env, runnableEnvCfg);
-        }
+        Object.assign(env, runnableEnvCfg);
     }
 
     return env;
@@ -140,7 +121,11 @@ export async function createTaskFromRunnable(
         };
         options = {
             cwd: runnableArgs.workspaceRoot || ".",
-            env: prepareEnv(true, runnable.label, runnableArgs, config.runnablesExtraEnv),
+            env: prepareEnv(
+                true,
+                runnableArgs.environment,
+                config.runnablesExtraEnv(runnable.label),
+            ),
         };
     } else {
         const runnableArgs = runnable.args;
diff --git a/src/tools/rust-analyzer/editors/code/tests/unit/runnable_env.test.ts b/src/tools/rust-analyzer/editors/code/tests/unit/runnable_env.test.ts
deleted file mode 100644
index f0a62a3cce2..00000000000
--- a/src/tools/rust-analyzer/editors/code/tests/unit/runnable_env.test.ts
+++ /dev/null
@@ -1,122 +0,0 @@
-import * as assert from "assert";
-import { prepareEnv } from "../../src/run";
-import type { RunnableEnvCfg } from "../../src/config";
-import type { Context } from ".";
-import type * as ra from "../../src/lsp_ext";
-
-function makeRunnable(label: string): ra.Runnable {
-    return {
-        label,
-        kind: "cargo",
-        args: {
-            cargoArgs: [],
-            cwd: ".",
-            executableArgs: [],
-        },
-    };
-}
-
-function fakePrepareEnv(runnableName: string, config?: RunnableEnvCfg): Record<string, string> {
-    const runnable = makeRunnable(runnableName);
-    const runnableArgs = runnable.args as ra.CargoRunnableArgs;
-    return prepareEnv(false, runnable.label, runnableArgs, config);
-}
-
-export async function getTests(ctx: Context) {
-    await ctx.suite("Runnable env", (suite) => {
-        suite.addTest("Global config works", async () => {
-            const binEnv = fakePrepareEnv("run project_name", { GLOBAL: "g" });
-            assert.strictEqual(binEnv["GLOBAL"], "g");
-
-            const testEnv = fakePrepareEnv("test some::mod::test_name", { GLOBAL: "g" });
-            assert.strictEqual(testEnv["GLOBAL"], "g");
-        });
-
-        suite.addTest("null mask works", async () => {
-            const config = [
-                {
-                    env: { DATA: "data" },
-                },
-            ];
-            const binEnv = fakePrepareEnv("run project_name", config);
-            assert.strictEqual(binEnv["DATA"], "data");
-
-            const testEnv = fakePrepareEnv("test some::mod::test_name", config);
-            assert.strictEqual(testEnv["DATA"], "data");
-        });
-
-        suite.addTest("order works", async () => {
-            const config = [
-                {
-                    env: { DATA: "data" },
-                },
-                {
-                    env: { DATA: "newdata" },
-                },
-            ];
-            const binEnv = fakePrepareEnv("run project_name", config);
-            assert.strictEqual(binEnv["DATA"], "newdata");
-
-            const testEnv = fakePrepareEnv("test some::mod::test_name", config);
-            assert.strictEqual(testEnv["DATA"], "newdata");
-        });
-
-        suite.addTest("mask works", async () => {
-            const config = [
-                {
-                    env: { DATA: "data" },
-                },
-                {
-                    mask: "^run",
-                    env: { DATA: "rundata" },
-                },
-                {
-                    mask: "special_test$",
-                    env: { DATA: "special_test" },
-                },
-            ];
-            const binEnv = fakePrepareEnv("run project_name", config);
-            assert.strictEqual(binEnv["DATA"], "rundata");
-
-            const testEnv = fakePrepareEnv("test some::mod::test_name", config);
-            assert.strictEqual(testEnv["DATA"], "data");
-
-            const specialTestEnv = fakePrepareEnv("test some::mod::special_test", config);
-            assert.strictEqual(specialTestEnv["DATA"], "special_test");
-        });
-
-        suite.addTest("exact test name works", async () => {
-            const config = [
-                {
-                    env: { DATA: "data" },
-                },
-                {
-                    mask: "some::mod::test_name",
-                    env: { DATA: "test special" },
-                },
-            ];
-            const testEnv = fakePrepareEnv("test some::mod::test_name", config);
-            assert.strictEqual(testEnv["DATA"], "test special");
-
-            const specialTestEnv = fakePrepareEnv("test some::mod::another_test", config);
-            assert.strictEqual(specialTestEnv["DATA"], "data");
-        });
-
-        suite.addTest("test mod name works", async () => {
-            const config = [
-                {
-                    env: { DATA: "data" },
-                },
-                {
-                    mask: "some::mod",
-                    env: { DATA: "mod special" },
-                },
-            ];
-            const testEnv = fakePrepareEnv("test some::mod::test_name", config);
-            assert.strictEqual(testEnv["DATA"], "mod special");
-
-            const specialTestEnv = fakePrepareEnv("test some::mod::another_test", config);
-            assert.strictEqual(specialTestEnv["DATA"], "mod special");
-        });
-    });
-}