This commit is contained in:
David Barsky 2023-03-09 15:27:24 -05:00
parent 8af3d6367e
commit 46e022098f
8 changed files with 58 additions and 37 deletions

View File

@ -1920,4 +1920,4 @@
} }
] ]
} }
} }

View File

@ -756,14 +756,18 @@ export function addProject(ctx: CtxInit): Cmd {
return; return;
} }
let workspaces: JsonProject[] = await Promise.all(vscode.workspace.workspaceFolders!.map(async (folder): Promise<JsonProject> => { const workspaces: JsonProject[] = await Promise.all(
return discoverWorkspace(vscode.workspace.textDocuments, discoverProjectCommand, { cwd: folder.uri.fsPath }); vscode.workspace.workspaceFolders!.map(async (folder): Promise<JsonProject> => {
})); return discoverWorkspace(vscode.workspace.textDocuments, discoverProjectCommand, {
cwd: folder.uri.fsPath,
});
})
);
await ctx.client.sendRequest(ra.addProject, { await ctx.client.sendRequest(ra.addProject, {
project: workspaces project: workspaces,
}); });
} };
} }
async function showReferencesImpl( async function showReferencesImpl(

View File

@ -215,7 +215,7 @@ export class Config {
} }
get discoverProjectCommand() { get discoverProjectCommand() {
return this.get<string[] | undefined>("discoverProjectCommand") return this.get<string[] | undefined>("discoverProjectCommand");
} }
get cargoRunner() { get cargoRunner() {

View File

@ -4,7 +4,14 @@ import * as ra from "./lsp_ext";
import { Config, substituteVSCodeVariables } from "./config"; import { Config, substituteVSCodeVariables } from "./config";
import { createClient } from "./client"; import { createClient } from "./client";
import { executeDiscoverProject, isRustDocument, isRustEditor, LazyOutputChannel, log, RustEditor } from "./util"; import {
executeDiscoverProject,
isRustDocument,
isRustEditor,
LazyOutputChannel,
log,
RustEditor,
} from "./util";
import { ServerStatusParams } from "./lsp_ext"; import { ServerStatusParams } from "./lsp_ext";
import { PersistentState } from "./persistent_state"; import { PersistentState } from "./persistent_state";
import { bootstrap } from "./bootstrap"; import { bootstrap } from "./bootstrap";
@ -17,12 +24,12 @@ import { ExecOptions } from "child_process";
export type Workspace = export type Workspace =
| { kind: "Empty" } | { kind: "Empty" }
| { | {
kind: "Workspace Folder"; kind: "Workspace Folder";
} }
| { | {
kind: "Detached Files"; kind: "Detached Files";
files: vscode.TextDocument[]; files: vscode.TextDocument[];
}; };
export function fetchWorkspace(): Workspace { export function fetchWorkspace(): Workspace {
const folders = (vscode.workspace.workspaceFolders || []).filter( const folders = (vscode.workspace.workspaceFolders || []).filter(
@ -36,13 +43,17 @@ export function fetchWorkspace(): Workspace {
? rustDocuments.length === 0 ? rustDocuments.length === 0
? { kind: "Empty" } ? { kind: "Empty" }
: { : {
kind: "Detached Files", kind: "Detached Files",
files: rustDocuments, files: rustDocuments,
} }
: { kind: "Workspace Folder" }; : { kind: "Workspace Folder" };
} }
export async function discoverWorkspace(files: readonly vscode.TextDocument[], command: string[], options: ExecOptions): Promise<JsonProject> { export async function discoverWorkspace(
files: readonly vscode.TextDocument[],
command: string[],
options: ExecOptions
): Promise<JsonProject> {
const paths = files.map((f) => f.uri.fsPath).join(" "); const paths = files.map((f) => f.uri.fsPath).join(" ");
const joinedCommand = command.join(" "); const joinedCommand = command.join(" ");
const data = await executeDiscoverProject(`${joinedCommand} -- ${paths}`, options); const data = await executeDiscoverProject(`${joinedCommand} -- ${paths}`, options);
@ -80,7 +91,7 @@ export class Ctx {
constructor( constructor(
readonly extCtx: vscode.ExtensionContext, readonly extCtx: vscode.ExtensionContext,
commandFactories: Record<string, CommandFactory>, commandFactories: Record<string, CommandFactory>,
workspace: Workspace, workspace: Workspace
) { ) {
extCtx.subscriptions.push(this); extCtx.subscriptions.push(this);
this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
@ -180,16 +191,22 @@ export class Ctx {
const discoverProjectCommand = this.config.discoverProjectCommand; const discoverProjectCommand = this.config.discoverProjectCommand;
if (discoverProjectCommand) { if (discoverProjectCommand) {
let workspaces: JsonProject[] = await Promise.all(vscode.workspace.workspaceFolders!.map(async (folder): Promise<JsonProject> => { const workspaces: JsonProject[] = await Promise.all(
return discoverWorkspace(vscode.workspace.textDocuments, discoverProjectCommand, { cwd: folder.uri.fsPath }); vscode.workspace.workspaceFolders!.map(async (folder): Promise<JsonProject> => {
})); return discoverWorkspace(
vscode.workspace.textDocuments,
discoverProjectCommand,
{ cwd: folder.uri.fsPath }
);
})
);
this.discoveredWorkspaces = workspaces; this.discoveredWorkspaces = workspaces;
} }
let initializationOptions = substituteVSCodeVariables(rawInitializationOptions); const initializationOptions = substituteVSCodeVariables(rawInitializationOptions);
// this appears to be load-bearing, for better or worse. // this appears to be load-bearing, for better or worse.
await initializationOptions.update('linkedProjects', this.discoveredWorkspaces) await initializationOptions.update("linkedProjects", this.discoveredWorkspaces);
this._client = await createClient( this._client = await createClient(
this.traceOutputChannel, this.traceOutputChannel,

View File

@ -45,7 +45,7 @@ export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, Te
export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace"); export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");
export const addProject = new lc.RequestType<AddProjectParams, string, void>( export const addProject = new lc.RequestType<AddProjectParams, string, void>(
"rust-analyzer/addProject" "rust-analyzer/addProject"
) );
export const runFlycheck = new lc.NotificationType<{ export const runFlycheck = new lc.NotificationType<{
textDocument: lc.TextDocumentIdentifier | null; textDocument: lc.TextDocumentIdentifier | null;

View File

@ -24,11 +24,11 @@ export async function activate(
vscode.window vscode.window
.showWarningMessage( .showWarningMessage(
`You have both the rust-analyzer (rust-lang.rust-analyzer) and Rust (rust-lang.rust) ` + `You have both the rust-analyzer (rust-lang.rust-analyzer) and Rust (rust-lang.rust) ` +
"plugins enabled. These are known to conflict and cause various functions of " + "plugins enabled. These are known to conflict and cause various functions of " +
"both plugins to not work correctly. You should disable one of them.", "both plugins to not work correctly. You should disable one of them.",
"Got it" "Got it"
) )
.then(() => { }, console.error); .then(() => {}, console.error);
} }
const ctx = new Ctx(context, createCommands(), fetchWorkspace()); const ctx = new Ctx(context, createCommands(), fetchWorkspace());
@ -146,7 +146,7 @@ function createCommands(): Record<string, CommandFactory> {
health: "stopped", health: "stopped",
}); });
}, },
disabled: (_) => async () => { }, disabled: (_) => async () => {},
}, },
analyzerStatus: { enabled: commands.analyzerStatus }, analyzerStatus: { enabled: commands.analyzerStatus },

View File

@ -60,9 +60,9 @@ interface Crate {
/// rust-analyzer assumes that files from one /// rust-analyzer assumes that files from one
/// source can't refer to files in another source. /// source can't refer to files in another source.
source?: { source?: {
include_dirs: string[], include_dirs: string[];
exclude_dirs: string[], exclude_dirs: string[];
}, };
/// The set of cfgs activated for a given crate, like /// The set of cfgs activated for a given crate, like
/// `["unix", "feature=\"foo\"", "feature=\"bar\""]`. /// `["unix", "feature=\"foo\"", "feature=\"bar\""]`.
cfg: string[]; cfg: string[];
@ -73,7 +73,7 @@ interface Crate {
target?: string; target?: string;
/// Environment variables, used for /// Environment variables, used for
/// the `env!` macro /// the `env!` macro
env: { [key: string]: string; }, env: { [key: string]: string };
/// Whether the crate is a proc-macro crate. /// Whether the crate is a proc-macro crate.
is_proc_macro: boolean; is_proc_macro: boolean;
@ -84,8 +84,8 @@ interface Crate {
interface Dep { interface Dep {
/// Index of a crate in the `crates` array. /// Index of a crate in the `crates` array.
crate: number, crate: number;
/// Name as should appear in the (implicit) /// Name as should appear in the (implicit)
/// `extern crate name` declaration. /// `extern crate name` declaration.
name: string, name: string;
} }

View File

@ -150,7 +150,7 @@ export function memoizeAsync<Ret, TThis, Param extends string>(
/** Awaitable wrapper around `child_process.exec` */ /** Awaitable wrapper around `child_process.exec` */
export function execute(command: string, options: ExecOptions): Promise<string> { export function execute(command: string, options: ExecOptions): Promise<string> {
log.info(`running command: ${command}`) log.info(`running command: ${command}`);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
exec(command, options, (err, stdout, stderr) => { exec(command, options, (err, stdout, stderr) => {
if (err) { if (err) {
@ -170,7 +170,7 @@ export function execute(command: string, options: ExecOptions): Promise<string>
} }
export function executeDiscoverProject(command: string, options: ExecOptions): Promise<string> { export function executeDiscoverProject(command: string, options: ExecOptions): Promise<string> {
log.info(`running command: ${command}`) log.info(`running command: ${command}`);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
exec(command, options, (err, stdout, _) => { exec(command, options, (err, stdout, _) => {
if (err) { if (err) {