diff options
Diffstat (limited to 'editors/code/src')
-rw-r--r-- | editors/code/src/main.ts | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 4d4513869..3405634f3 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import * as vscode from 'vscode'; | 1 | import * as vscode from 'vscode'; |
2 | import * as path from "path"; | 2 | import * as path from "path"; |
3 | import * as os from "os"; | 3 | import * as os from "os"; |
4 | import { promises as fs } from "fs"; | 4 | import { promises as fs, PathLike } from "fs"; |
5 | 5 | ||
6 | import * as commands from './commands'; | 6 | import * as commands from './commands'; |
7 | import { activateInlayHints } from './inlay_hints'; | 7 | import { activateInlayHints } from './inlay_hints'; |
@@ -12,6 +12,7 @@ import { log, assert, isValidExecutable } from './util'; | |||
12 | import { PersistentState } from './persistent_state'; | 12 | import { PersistentState } from './persistent_state'; |
13 | import { fetchRelease, download } from './net'; | 13 | import { fetchRelease, download } from './net'; |
14 | import { activateTaskProvider } from './tasks'; | 14 | import { activateTaskProvider } from './tasks'; |
15 | import { exec } from 'child_process'; | ||
15 | 16 | ||
16 | let ctx: Ctx | undefined; | 17 | let ctx: Ctx | undefined; |
17 | 18 | ||
@@ -188,6 +189,46 @@ async function bootstrapServer(config: Config, state: PersistentState): Promise< | |||
188 | return path; | 189 | return path; |
189 | } | 190 | } |
190 | 191 | ||
192 | async function patchelf(dest: PathLike): Promise<void> { | ||
193 | await vscode.window.withProgress( | ||
194 | { | ||
195 | location: vscode.ProgressLocation.Notification, | ||
196 | title: "Patching rust-analyzer for NixOS" | ||
197 | }, | ||
198 | async (progress, _) => { | ||
199 | const expression = ` | ||
200 | {src, pkgs ? import <nixpkgs> {}}: | ||
201 | pkgs.stdenv.mkDerivation { | ||
202 | name = "rust-analyzer"; | ||
203 | inherit src; | ||
204 | phases = [ "installPhase" "fixupPhase" ]; | ||
205 | installPhase = "cp $src $out"; | ||
206 | fixupPhase = '' | ||
207 | chmod 755 $out | ||
208 | patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out | ||
209 | ''; | ||
210 | } | ||
211 | `; | ||
212 | const origFile = dest + "-orig"; | ||
213 | await fs.rename(dest, origFile); | ||
214 | progress.report({ message: "Patching executable", increment: 20 }); | ||
215 | await new Promise((resolve, reject) => { | ||
216 | const handle = exec(`nix-build -E - --arg src '${origFile}' -o ${dest}`, | ||
217 | (err, stdout, stderr) => { | ||
218 | if (err != null) { | ||
219 | reject(Error(stderr)); | ||
220 | } else { | ||
221 | resolve(stdout); | ||
222 | } | ||
223 | }); | ||
224 | handle.stdin?.write(expression); | ||
225 | handle.stdin?.end(); | ||
226 | }); | ||
227 | await fs.unlink(origFile); | ||
228 | } | ||
229 | ); | ||
230 | } | ||
231 | |||
191 | async function getServer(config: Config, state: PersistentState): Promise<string | undefined> { | 232 | async function getServer(config: Config, state: PersistentState): Promise<string | undefined> { |
192 | const explicitPath = process.env.__RA_LSP_SERVER_DEBUG ?? config.serverPath; | 233 | const explicitPath = process.env.__RA_LSP_SERVER_DEBUG ?? config.serverPath; |
193 | if (explicitPath) { | 234 | if (explicitPath) { |
@@ -237,6 +278,12 @@ async function getServer(config: Config, state: PersistentState): Promise<string | |||
237 | assert(!!artifact, `Bad release: ${JSON.stringify(release)}`); | 278 | assert(!!artifact, `Bad release: ${JSON.stringify(release)}`); |
238 | 279 | ||
239 | await download(artifact.browser_download_url, dest, "Downloading rust-analyzer server", { mode: 0o755 }); | 280 | await download(artifact.browser_download_url, dest, "Downloading rust-analyzer server", { mode: 0o755 }); |
281 | |||
282 | // Patching executable if that's NixOS. | ||
283 | if (await fs.stat("/etc/nixos").then(_ => true).catch(_ => false)) { | ||
284 | await patchelf(dest); | ||
285 | } | ||
286 | |||
240 | await state.updateServerVersion(config.package.version); | 287 | await state.updateServerVersion(config.package.version); |
241 | return dest; | 288 | return dest; |
242 | } | 289 | } |