about summary refs log tree commit diff
path: root/editors/code/src/client.ts
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src/client.ts')
-rw-r--r--editors/code/src/client.ts65
1 files changed, 34 insertions, 31 deletions
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 05d4d08f70b..fb667619c86 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -4,9 +4,7 @@ import * as ra from "../src/lsp_ext";
 import * as Is from "vscode-languageclient/lib/common/utils/is";
 import { assert } from "./util";
 import { WorkspaceEdit } from "vscode";
-import { Workspace } from "./ctx";
-import { substituteVariablesInEnv } from "./config";
-import { outputChannel, traceOutputChannel } from "./main";
+import { substituteVSCodeVariables } from "./config";
 import { randomUUID } from "crypto";
 
 export interface Env {
@@ -65,40 +63,42 @@ function renderHoverActions(actions: ra.CommandLinkGroup[]): vscode.MarkdownStri
 }
 
 export async function createClient(
-    serverPath: string,
-    workspace: Workspace,
-    extraEnv: Env
+    traceOutputChannel: vscode.OutputChannel,
+    outputChannel: vscode.OutputChannel,
+    initializationOptions: vscode.WorkspaceConfiguration,
+    serverOptions: lc.ServerOptions
 ): Promise<lc.LanguageClient> {
-    // '.' Is the fallback if no folder is open
-    // TODO?: Workspace folders support Uri's (eg: file://test.txt).
-    // It might be a good idea to test if the uri points to a file.
-
-    const newEnv = substituteVariablesInEnv(Object.assign({}, process.env, extraEnv));
-    const run: lc.Executable = {
-        command: serverPath,
-        options: { env: newEnv },
-    };
-    const serverOptions: lc.ServerOptions = {
-        run,
-        debug: run,
-    };
-
-    let initializationOptions = vscode.workspace.getConfiguration("rust-analyzer");
-
-    if (workspace.kind === "Detached Files") {
-        initializationOptions = {
-            detachedFiles: workspace.files.map((file) => file.uri.fsPath),
-            ...initializationOptions,
-        };
-    }
-
     const clientOptions: lc.LanguageClientOptions = {
         documentSelector: [{ scheme: "file", language: "rust" }],
         initializationOptions,
         diagnosticCollectionName: "rustc",
-        traceOutputChannel: traceOutputChannel(),
-        outputChannel: outputChannel(),
+        traceOutputChannel,
+        outputChannel,
         middleware: {
+            workspace: {
+                // HACK: This is a workaround, when the client has been disposed, VSCode
+                // continues to emit events to the client and the default one for this event
+                // attempt to restart the client for no reason
+                async didChangeWatchedFile(event, next) {
+                    if (client.isRunning()) {
+                        await next(event);
+                    }
+                },
+                async configuration(
+                    params: lc.ConfigurationParams,
+                    token: vscode.CancellationToken,
+                    next: lc.ConfigurationRequest.HandlerSignature
+                ) {
+                    const resp = await next(params, token);
+                    if (resp && Array.isArray(resp)) {
+                        return resp.map((val) => {
+                            return substituteVSCodeVariables(val);
+                        });
+                    } else {
+                        return resp;
+                    }
+                },
+            },
             async provideHover(
                 document: vscode.TextDocument,
                 position: vscode.Position,
@@ -255,6 +255,9 @@ export async function createClient(
 }
 
 class ExperimentalFeatures implements lc.StaticFeature {
+    getState(): lc.FeatureState {
+        return { kind: "static" };
+    }
     fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
         const caps: any = capabilities.experimental ?? {};
         caps.snippetTextEdit = true;