From 8af3d6367ecead0abf80e697176f697d97c25215 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Thu, 9 Mar 2023 15:06:26 -0500 Subject: This commit add Cargo-style project discovery for Buck and Bazel users. This feature requires the user to add a command that generates a `rust-project.json` from a set of files. Project discovery can be invoked in two ways: 1. At extension activation time, which includes the generated `rust-project.json` as part of the linkedProjects argument in InitializeParams 2. Through a new command titled "Add current file to workspace", which makes use of a new, rust-analyzer specific LSP request that adds the workspace without erasing any existing workspaces. I think that the command-running functionality _could_ merit being placed into its own extension (and expose it via extension contribution points), if only provide build-system idiomatic progress reporting and status handling, but I haven't (yet) made an extension that does this. --- editors/code/package.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'editors/code/package.json') diff --git a/editors/code/package.json b/editors/code/package.json index a3b1a3107d0..e79ab33726d 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -199,6 +199,11 @@ "title": "Reload workspace", "category": "rust-analyzer" }, + { + "command": "rust-analyzer.addProject", + "title": "Add current file to workspace", + "category": "rust-analyzer" + }, { "command": "rust-analyzer.reload", "title": "Restart server", @@ -447,6 +452,17 @@ "Fill missing expressions with reasonable defaults, `new` or `default` constructors." ] }, + "rust-analyzer.discoverProjectCommand": { + "markdownDescription": "Sets the command that rust-analyzer uses to generate `rust-project.json` files. This command is\n only suggested if a build system like Buck or Bazel is used. The command must accept files as arguements and return \n a rust-project.json over stdout.", + "default": null, + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + } + }, "rust-analyzer.cachePriming.enable": { "markdownDescription": "Warm up caches on project load.", "default": true, @@ -1904,4 +1920,4 @@ } ] } -} +} \ No newline at end of file -- cgit 1.4.1-3-g733a5 From 46e022098feda31c98120ca58b6ce02b45cdedf9 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Thu, 9 Mar 2023 15:27:24 -0500 Subject: fmt --- editors/code/package.json | 2 +- editors/code/src/commands.ts | 14 ++++++++---- editors/code/src/config.ts | 2 +- editors/code/src/ctx.ts | 49 +++++++++++++++++++++++++++------------- editors/code/src/lsp_ext.ts | 2 +- editors/code/src/main.ts | 8 +++---- editors/code/src/rust_project.ts | 14 ++++++------ editors/code/src/util.ts | 4 ++-- 8 files changed, 58 insertions(+), 37 deletions(-) (limited to 'editors/code/package.json') diff --git a/editors/code/package.json b/editors/code/package.json index e79ab33726d..0a3e4103f6e 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -1920,4 +1920,4 @@ } ] } -} \ No newline at end of file +} diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index beff8501dc8..a8ec75a78aa 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -756,14 +756,18 @@ export function addProject(ctx: CtxInit): Cmd { return; } - let workspaces: JsonProject[] = await Promise.all(vscode.workspace.workspaceFolders!.map(async (folder): Promise => { - return discoverWorkspace(vscode.workspace.textDocuments, discoverProjectCommand, { cwd: folder.uri.fsPath }); - })); + const workspaces: JsonProject[] = await Promise.all( + vscode.workspace.workspaceFolders!.map(async (folder): Promise => { + return discoverWorkspace(vscode.workspace.textDocuments, discoverProjectCommand, { + cwd: folder.uri.fsPath, + }); + }) + ); await ctx.client.sendRequest(ra.addProject, { - project: workspaces + project: workspaces, }); - } + }; } async function showReferencesImpl( diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts index f62843dffa6..1dae603714d 100644 --- a/editors/code/src/config.ts +++ b/editors/code/src/config.ts @@ -215,7 +215,7 @@ export class Config { } get discoverProjectCommand() { - return this.get("discoverProjectCommand") + return this.get("discoverProjectCommand"); } get cargoRunner() { diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index ba2d4e97af1..5b019d6aeb5 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -4,7 +4,14 @@ import * as ra from "./lsp_ext"; import { Config, substituteVSCodeVariables } from "./config"; 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 { PersistentState } from "./persistent_state"; import { bootstrap } from "./bootstrap"; @@ -17,12 +24,12 @@ import { ExecOptions } from "child_process"; export type Workspace = | { kind: "Empty" } | { - kind: "Workspace Folder"; - } + kind: "Workspace Folder"; + } | { - kind: "Detached Files"; - files: vscode.TextDocument[]; - }; + kind: "Detached Files"; + files: vscode.TextDocument[]; + }; export function fetchWorkspace(): Workspace { const folders = (vscode.workspace.workspaceFolders || []).filter( @@ -36,13 +43,17 @@ export function fetchWorkspace(): Workspace { ? rustDocuments.length === 0 ? { kind: "Empty" } : { - kind: "Detached Files", - files: rustDocuments, - } + kind: "Detached Files", + files: rustDocuments, + } : { kind: "Workspace Folder" }; } -export async function discoverWorkspace(files: readonly vscode.TextDocument[], command: string[], options: ExecOptions): Promise { +export async function discoverWorkspace( + files: readonly vscode.TextDocument[], + command: string[], + options: ExecOptions +): Promise { const paths = files.map((f) => f.uri.fsPath).join(" "); const joinedCommand = command.join(" "); const data = await executeDiscoverProject(`${joinedCommand} -- ${paths}`, options); @@ -80,7 +91,7 @@ export class Ctx { constructor( readonly extCtx: vscode.ExtensionContext, commandFactories: Record, - workspace: Workspace, + workspace: Workspace ) { extCtx.subscriptions.push(this); this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); @@ -180,16 +191,22 @@ export class Ctx { const discoverProjectCommand = this.config.discoverProjectCommand; if (discoverProjectCommand) { - let workspaces: JsonProject[] = await Promise.all(vscode.workspace.workspaceFolders!.map(async (folder): Promise => { - return discoverWorkspace(vscode.workspace.textDocuments, discoverProjectCommand, { cwd: folder.uri.fsPath }); - })); + const workspaces: JsonProject[] = await Promise.all( + vscode.workspace.workspaceFolders!.map(async (folder): Promise => { + return discoverWorkspace( + vscode.workspace.textDocuments, + discoverProjectCommand, + { cwd: folder.uri.fsPath } + ); + }) + ); this.discoveredWorkspaces = workspaces; } - let initializationOptions = substituteVSCodeVariables(rawInitializationOptions); + const initializationOptions = substituteVSCodeVariables(rawInitializationOptions); // 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.traceOutputChannel, diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts index 6c8428aa972..942573c0f16 100644 --- a/editors/code/src/lsp_ext.ts +++ b/editors/code/src/lsp_ext.ts @@ -45,7 +45,7 @@ export const relatedTests = new lc.RequestType("rust-analyzer/reloadWorkspace"); export const addProject = new lc.RequestType( "rust-analyzer/addProject" -) +); export const runFlycheck = new lc.NotificationType<{ textDocument: lc.TextDocumentIdentifier | null; diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 323aa89ef06..d5de00561b1 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -24,11 +24,11 @@ export async function activate( vscode.window .showWarningMessage( `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 " + - "both plugins to not work correctly. You should disable one of them.", + "plugins enabled. These are known to conflict and cause various functions of " + + "both plugins to not work correctly. You should disable one of them.", "Got it" ) - .then(() => { }, console.error); + .then(() => {}, console.error); } const ctx = new Ctx(context, createCommands(), fetchWorkspace()); @@ -146,7 +146,7 @@ function createCommands(): Record { health: "stopped", }); }, - disabled: (_) => async () => { }, + disabled: (_) => async () => {}, }, analyzerStatus: { enabled: commands.analyzerStatus }, diff --git a/editors/code/src/rust_project.ts b/editors/code/src/rust_project.ts index adf0f89c961..187a1a96c10 100644 --- a/editors/code/src/rust_project.ts +++ b/editors/code/src/rust_project.ts @@ -60,9 +60,9 @@ interface Crate { /// rust-analyzer assumes that files from one /// source can't refer to files in another source. source?: { - include_dirs: string[], - exclude_dirs: string[], - }, + include_dirs: string[]; + exclude_dirs: string[]; + }; /// The set of cfgs activated for a given crate, like /// `["unix", "feature=\"foo\"", "feature=\"bar\""]`. cfg: string[]; @@ -73,7 +73,7 @@ interface Crate { target?: string; /// Environment variables, used for /// the `env!` macro - env: { [key: string]: string; }, + env: { [key: string]: string }; /// Whether the crate is a proc-macro crate. is_proc_macro: boolean; @@ -84,8 +84,8 @@ interface Crate { interface Dep { /// Index of a crate in the `crates` array. - crate: number, + crate: number; /// Name as should appear in the (implicit) /// `extern crate name` declaration. - name: string, -} \ No newline at end of file + name: string; +} diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts index d2ecdce5b4e..922fbcbcf35 100644 --- a/editors/code/src/util.ts +++ b/editors/code/src/util.ts @@ -150,7 +150,7 @@ export function memoizeAsync( /** Awaitable wrapper around `child_process.exec` */ export function execute(command: string, options: ExecOptions): Promise { - log.info(`running command: ${command}`) + log.info(`running command: ${command}`); return new Promise((resolve, reject) => { exec(command, options, (err, stdout, stderr) => { if (err) { @@ -170,7 +170,7 @@ export function execute(command: string, options: ExecOptions): Promise } export function executeDiscoverProject(command: string, options: ExecOptions): Promise { - log.info(`running command: ${command}`) + log.info(`running command: ${command}`); return new Promise((resolve, reject) => { exec(command, options, (err, stdout, _) => { if (err) { -- cgit 1.4.1-3-g733a5 From 68d3eaead4100a32e705161ee0136121882949f1 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Thu, 9 Mar 2023 16:14:41 -0500 Subject: fix typo in package.json. --- editors/code/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'editors/code/package.json') diff --git a/editors/code/package.json b/editors/code/package.json index 0a3e4103f6e..1e8cdb2eaa7 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -453,7 +453,7 @@ ] }, "rust-analyzer.discoverProjectCommand": { - "markdownDescription": "Sets the command that rust-analyzer uses to generate `rust-project.json` files. This command is\n only suggested if a build system like Buck or Bazel is used. The command must accept files as arguements and return \n a rust-project.json over stdout.", + "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.", "default": null, "type": [ "null", @@ -1920,4 +1920,4 @@ } ] } -} +} \ No newline at end of file -- cgit 1.4.1-3-g733a5 From 91371494eec262d6e8966f905497ee2e3c384181 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Fri, 10 Mar 2023 13:09:16 -0500 Subject: move `rust-analyzer.discoverProjectCommand` above `$generated-start` to avoid failing tests --- editors/code/package.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'editors/code/package.json') diff --git a/editors/code/package.json b/editors/code/package.json index 1e8cdb2eaa7..1e7e3b6cd5d 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -433,6 +433,17 @@ "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.", + "default": null, + "type": [ + "null", + "array" + ], + "items": { + "type": "string" + } + }, "$generated-start": {}, "rust-analyzer.assist.emitMustUse": { "markdownDescription": "Whether to insert #[must_use] when generating `as_` methods\nfor enum variants.", @@ -452,17 +463,6 @@ "Fill missing expressions with reasonable defaults, `new` or `default` constructors." ] }, - "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.", - "default": null, - "type": [ - "null", - "array" - ], - "items": { - "type": "string" - } - }, "rust-analyzer.cachePriming.enable": { "markdownDescription": "Warm up caches on project load.", "default": true, -- cgit 1.4.1-3-g733a5 From cb93c12c3114429866329a93e67ec1c5e8f779ff Mon Sep 17 00:00:00 2001 From: David Barsky Date: Mon, 13 Mar 2023 13:33:39 -0400 Subject: fmt --- editors/code/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/package.json') diff --git a/editors/code/package.json b/editors/code/package.json index 1e7e3b6cd5d..e2015a67e53 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -1920,4 +1920,4 @@ } ] } -} \ No newline at end of file +} -- cgit 1.4.1-3-g733a5 From 78aed305e1980ccf70c2b3f1405db38521a11d54 Mon Sep 17 00:00:00 2001 From: David Barsky Date: Mon, 13 Mar 2023 15:37:58 -0400 Subject: rename "addProject" command --- editors/code/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'editors/code/package.json') diff --git a/editors/code/package.json b/editors/code/package.json index e2015a67e53..c5eb08748bf 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -201,7 +201,7 @@ }, { "command": "rust-analyzer.addProject", - "title": "Add current file to workspace", + "title": "Add current file's crate to workspace", "category": "rust-analyzer" }, { -- cgit 1.4.1-3-g733a5