X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=editors%2Fcode%2Fsrc%2Fmain.ts;h=0e5a206410e0a4e6dcedbfb77b60b41f84b447c2;hb=5dab5e737909532e4a65390541393af6ee72f65b;hp=980ed925b434480bacfd9408ec720110ee0f8139;hpb=d2619bf0ca0c8c2ff8cda22beec9851887e4a4d5;p=rust.git diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 980ed925b43..0e5a206410e 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -1,18 +1,18 @@ import * as vscode from 'vscode'; import * as path from "path"; import * as os from "os"; -import { promises as fs } from "fs"; +import { promises as fs, PathLike } from "fs"; import * as commands from './commands'; import { activateInlayHints } from './inlay_hints'; import { activateStatusDisplay } from './status_display'; import { Ctx } from './ctx'; -import { activateHighlighting } from './highlighting'; import { Config, NIGHTLY_TAG } from './config'; -import { log, assert } from './util'; +import { log, assert, isValidExecutable } from './util'; import { PersistentState } from './persistent_state'; import { fetchRelease, download } from './net'; -import { spawnSync } from 'child_process'; +import { activateTaskProvider } from './tasks'; +import { exec } from 'child_process'; let ctx: Ctx | undefined; @@ -41,11 +41,18 @@ export async function activate(context: vscode.ExtensionContext) { const state = new PersistentState(context.globalState); const serverPath = await bootstrap(config, state); + const workspaceFolder = vscode.workspace.workspaceFolders?.[0]; + if (workspaceFolder === undefined) { + const err = "Cannot activate rust-analyzer when no folder is opened"; + void vscode.window.showErrorMessage(err); + throw new Error(err); + } + // Note: we try to start the server before we activate type hints so that it // registers its `onDidChangeDocument` handler before us. // // This a horribly, horribly wrong way to deal with this problem. - ctx = await Ctx.create(config, context, serverPath); + ctx = await Ctx.create(config, context, serverPath, workspaceFolder.uri.fsPath); // Commands which invokes manually via command palette, shortcut, etc. @@ -71,26 +78,35 @@ export async function activate(context: vscode.ExtensionContext) { ctx.registerCommand('syntaxTree', commands.syntaxTree); ctx.registerCommand('expandMacro', commands.expandMacro); ctx.registerCommand('run', commands.run); + ctx.registerCommand('debug', commands.debug); + ctx.registerCommand('newDebugConfig', commands.newDebugConfig); defaultOnEnter.dispose(); ctx.registerCommand('onEnter', commands.onEnter); ctx.registerCommand('ssr', commands.ssr); ctx.registerCommand('serverVersion', commands.serverVersion); + ctx.registerCommand('toggleInlayHints', commands.toggleInlayHints); // Internal commands which are invoked by the server. ctx.registerCommand('runSingle', commands.runSingle); ctx.registerCommand('debugSingle', commands.debugSingle); ctx.registerCommand('showReferences', commands.showReferences); ctx.registerCommand('applySourceChange', commands.applySourceChange); - ctx.registerCommand('selectAndApplySourceChange', commands.selectAndApplySourceChange); + ctx.registerCommand('applySnippetWorkspaceEdit', commands.applySnippetWorkspaceEditCommand); + ctx.registerCommand('applyActionGroup', commands.applyActionGroup); + + ctx.pushCleanup(activateTaskProvider(workspaceFolder)); activateStatusDisplay(ctx); - if (!ctx.config.highlightingSemanticTokens) { - activateHighlighting(ctx); - } activateInlayHints(ctx); + + vscode.workspace.onDidChangeConfiguration( + _ => ctx?.client?.sendNotification('workspace/didChangeConfiguration', { settings: "" }), + null, + ctx.subscriptions, + ); } export async function deactivate() { @@ -165,16 +181,55 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise< ); } - const res = spawnSync(path, ["--version"], { encoding: 'utf8' }); - log.debug("Checked binary availability via --version", res); - log.debug(res, "--version output:", res.output); - if (res.status !== 0) { + log.debug("Using server binary at", path); + + if (!isValidExecutable(path)) { throw new Error(`Failed to execute ${path} --version`); } return path; } +async function patchelf(dest: PathLike): Promise { + await vscode.window.withProgress( + { + location: vscode.ProgressLocation.Notification, + title: "Patching rust-analyzer for NixOS" + }, + async (progress, _) => { + const expression = ` + {src, pkgs ? import {}}: + pkgs.stdenv.mkDerivation { + name = "rust-analyzer"; + inherit src; + phases = [ "installPhase" "fixupPhase" ]; + installPhase = "cp $src $out"; + fixupPhase = '' + chmod 755 $out + patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out + ''; + } + `; + const origFile = dest + "-orig"; + await fs.rename(dest, origFile); + progress.report({ message: "Patching executable", increment: 20 }); + await new Promise((resolve, reject) => { + const handle = exec(`nix-build -E - --arg src '${origFile}' -o ${dest}`, + (err, stdout, stderr) => { + if (err != null) { + reject(Error(stderr)); + } else { + resolve(stdout); + } + }); + handle.stdin?.write(expression); + handle.stdin?.end(); + }); + await fs.unlink(origFile); + } + ); +} + async function getServer(config: Config, state: PersistentState): Promise { const explicitPath = process.env.__RA_LSP_SERVER_DEBUG ?? config.serverPath; if (explicitPath) { @@ -224,6 +279,12 @@ async function getServer(config: Config, state: PersistentState): Promise true).catch(_ => false)) { + await patchelf(dest); + } + await state.updateServerVersion(config.package.version); return dest; }