code: yeet rust-analyzer.discoverProjectCommand

This commit is contained in:
David Barsky 2023-09-05 12:02:30 -04:00
parent caeea45999
commit b1b044f2d5
5 changed files with 19 additions and 67 deletions

View file

@ -471,16 +471,13 @@
"default": false,
"type": "boolean"
},
"rust-analyzer.discoverProjectCommand": {
"markdownDescription": "Sets the command that rust-analyzer uses to generate `rust-project.json` files. This command should only be used\n if a build system like Buck or Bazel is also in use. The command must accept files as arguments and return \n a rust-project.json over stdout.",
"rust-analyzer.discoverProjectRunner": {
"markdownDescription": "Sets the extension responsible for determining which extension the rust-analyzer extension uses to generate `rust-project.json` files. This should should only be used\n if a build system like Buck or Bazel is also in use.",
"default": null,
"type": [
"null",
"array"
],
"items": {
"type": "string"
}
"string"
]
},
"rust-analyzer.showUnlinkedFileNotification": {
"markdownDescription": "Whether to show a notification for unlinked files asking the user to add the corresponding Cargo.toml to the linked projects setting.",

View file

@ -3,7 +3,7 @@ import * as lc from "vscode-languageclient";
import * as ra from "./lsp_ext";
import * as path from "path";
import { type Ctx, type Cmd, type CtxInit, discoverWorkspace } from "./ctx";
import { type Ctx, type Cmd, type CtxInit } from "./ctx";
import { applySnippetWorkspaceEdit, applySnippetTextEdits } from "./snippets";
import { spawnSync } from "child_process";
import { type RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
@ -871,22 +871,16 @@ export function rebuildProcMacros(ctx: CtxInit): Cmd {
export function addProject(ctx: CtxInit): Cmd {
return async () => {
const discoverProjectCommand = ctx.config.discoverProjectCommand;
if (!discoverProjectCommand) {
const extensionName = ctx.config.discoverProjectRunner;
// this command shouldn't be enabled in the first place if this isn't set.
if (!extensionName) {
return;
}
const workspaces: JsonProject[] = await Promise.all(
vscode.workspace.textDocuments
.filter(isRustDocument)
.map(async (file): Promise<JsonProject> => {
return discoverWorkspace([file], discoverProjectCommand, {
cwd: path.dirname(file.uri.fsPath),
});
}),
);
const command = `${extensionName}.discoverWorkspaceCommand`;
const project = (await vscode.commands.executeCommand(command)) as JsonProject;
ctx.addToDiscoveredWorkspaces(workspaces);
ctx.addToDiscoveredWorkspaces([project]);
// this is a workaround to avoid needing writing the `rust-project.json` into
// a workspace-level VS Code-specific settings folder. We'd like to keep the

View file

@ -253,8 +253,8 @@ export class Config {
return this.get<boolean>("trace.extension");
}
get discoverProjectCommand() {
return this.get<string[] | undefined>("discoverProjectCommand");
get discoverProjectRunner(): string | undefined {
return this.get<string | undefined>("discoverProjectRunner");
}
get problemMatcher(): string[] {

View file

@ -1,12 +1,10 @@
import * as vscode from "vscode";
import type * as lc from "vscode-languageclient/node";
import * as ra from "./lsp_ext";
import * as path from "path";
import { Config, prepareVSCodeConfig } from "./config";
import { createClient } from "./client";
import {
executeDiscoverProject,
isDocumentInWorkspace,
isRustDocument,
isRustEditor,
@ -24,7 +22,6 @@ import {
import { execRevealDependency } from "./commands";
import { PersistentState } from "./persistent_state";
import { bootstrap } from "./bootstrap";
import type { ExecOptions } from "child_process";
// We only support local folders, not eg. Live Share (`vlsl:` scheme), so don't activate if
// only those are in use. We use "Empty" to represent these scenarios
@ -58,17 +55,6 @@ export function fetchWorkspace(): Workspace {
: { kind: "Workspace Folder" };
}
export async function discoverWorkspace(
files: readonly vscode.TextDocument[],
command: string[],
options: ExecOptions,
): Promise<JsonProject> {
const paths = files.map((f) => `"${f.uri.fsPath}"`).join(" ");
const joinedCommand = command.join(" ");
const data = await executeDiscoverProject(`${joinedCommand} ${paths}`, options);
return JSON.parse(data) as JsonProject;
}
export type CommandFactory = {
enabled: (ctx: CtxInit) => Cmd;
disabled?: (ctx: Ctx) => Cmd;
@ -200,6 +186,12 @@ export class Ctx {
};
let rawInitializationOptions = vscode.workspace.getConfiguration("rust-analyzer");
if (this.config.discoverProjectRunner) {
const command = `${this.config.discoverProjectRunner}.discoverWorkspaceCommand`;
log.info(`running command: ${command}`);
const project = (await vscode.commands.executeCommand(command)) as JsonProject;
this.addToDiscoveredWorkspaces([project]);
}
if (this.workspace.kind === "Detached Files") {
rawInitializationOptions = {
@ -208,21 +200,6 @@ export class Ctx {
};
}
const discoverProjectCommand = this.config.discoverProjectCommand;
if (discoverProjectCommand) {
const workspaces: JsonProject[] = await Promise.all(
vscode.workspace.textDocuments
.filter(isRustDocument)
.map(async (file): Promise<JsonProject> => {
return discoverWorkspace([file], discoverProjectCommand, {
cwd: path.dirname(file.uri.fsPath),
});
}),
);
this.addToDiscoveredWorkspaces(workspaces);
}
const initializationOptions = prepareVSCodeConfig(
rawInitializationOptions,
(key, obj) => {

View file

@ -154,22 +154,6 @@ export function execute(command: string, options: ExecOptions): Promise<string>
});
}
export function executeDiscoverProject(command: string, options: ExecOptions): Promise<string> {
options = Object.assign({ maxBuffer: 10 * 1024 * 1024 }, options);
log.info(`running command: ${command}`);
return new Promise((resolve, reject) => {
exec(command, options, (err, stdout, _) => {
if (err) {
log.error(err);
reject(err);
return;
}
resolve(stdout.trimEnd());
});
});
}
export class LazyOutputChannel implements vscode.OutputChannel {
constructor(name: string) {
this.name = name;