Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'editors/code/src/ctx.ts')
-rw-r--r--editors/code/src/ctx.ts103
1 files changed, 91 insertions, 12 deletions
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index c2dca733df..a72b5391ff 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -1,11 +1,13 @@
import * as vscode from "vscode";
import * 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,
LazyOutputChannel,
@@ -13,6 +15,13 @@ import {
RustEditor,
} from "./util";
import { ServerStatusParams } from "./lsp_ext";
+import {
+ Dependency,
+ DependencyFile,
+ RustDependenciesProvider,
+ DependencyId,
+} from "./dependencies_provider";
+import { execRevealDependency } from "./commands";
import { PersistentState } from "./persistent_state";
import { bootstrap } from "./bootstrap";
import { ExecOptions } from "child_process";
@@ -82,11 +91,22 @@ export class Ctx {
private state: PersistentState;
private commandFactories: Record<string, CommandFactory>;
private commandDisposables: Disposable[];
+ private unlinkedFiles: vscode.Uri[];
+ private _dependencies: RustDependenciesProvider | undefined;
+ private _treeView: vscode.TreeView<Dependency | DependencyFile | DependencyId> | undefined;
get client() {
return this._client;
}
+ get treeView() {
+ return this._treeView;
+ }
+
+ get dependencies() {
+ return this._dependencies;
+ }
+
constructor(
readonly extCtx: vscode.ExtensionContext,
commandFactories: Record<string, CommandFactory>,
@@ -94,12 +114,11 @@ export class Ctx {
) {
extCtx.subscriptions.push(this);
this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
- this.statusBar.show();
this.workspace = workspace;
this.clientSubscriptions = [];
this.commandDisposables = [];
this.commandFactories = commandFactories;
-
+ this.unlinkedFiles = [];
this.state = new PersistentState(extCtx.globalState);
this.config = new Config(extCtx);
@@ -191,12 +210,13 @@ export class Ctx {
const discoverProjectCommand = this.config.discoverProjectCommand;
if (discoverProjectCommand) {
const workspaces: JsonProject[] = await Promise.all(
- vscode.workspace.workspaceFolders!.map(async (folder): Promise<JsonProject> => {
- const rustDocuments = vscode.workspace.textDocuments.filter(isRustDocument);
- return discoverWorkspace(rustDocuments, discoverProjectCommand, {
- cwd: folder.uri.fsPath,
- });
- })
+ vscode.workspace.textDocuments
+ .filter(isRustDocument)
+ .map(async (file): Promise<JsonProject> => {
+ return discoverWorkspace([file], discoverProjectCommand, {
+ cwd: path.dirname(file.uri.fsPath),
+ });
+ })
);
this.addToDiscoveredWorkspaces(workspaces);
@@ -218,7 +238,8 @@ export class Ctx {
this.outputChannel,
initializationOptions,
serverOptions,
- this.config
+ this.config,
+ this.unlinkedFiles
);
this.pushClientCleanup(
this._client.onNotification(ra.serverStatus, (params) =>
@@ -242,6 +263,56 @@ export class Ctx {
}
await client.start();
this.updateCommands();
+
+ if (this.config.showDependenciesExplorer) {
+ this.prepareTreeDependenciesView(client);
+ }
+ }
+
+ private prepareTreeDependenciesView(client: lc.LanguageClient) {
+ const ctxInit: CtxInit = {
+ ...this,
+ client: client,
+ };
+ this._dependencies = new RustDependenciesProvider(ctxInit);
+ this._treeView = vscode.window.createTreeView("rustDependencies", {
+ treeDataProvider: this._dependencies,
+ showCollapseAll: true,
+ });
+
+ this.pushExtCleanup(this._treeView);
+ vscode.window.onDidChangeActiveTextEditor(async (e) => {
+ // we should skip documents that belong to the current workspace
+ if (this.shouldRevealDependency(e)) {
+ try {
+ await execRevealDependency(e);
+ } catch (reason) {
+ await vscode.window.showErrorMessage(`Dependency error: ${reason}`);
+ }
+ }
+ });
+
+ this.treeView?.onDidChangeVisibility(async (e) => {
+ if (e.visible) {
+ const activeEditor = vscode.window.activeTextEditor;
+ if (this.shouldRevealDependency(activeEditor)) {
+ try {
+ await execRevealDependency(activeEditor);
+ } catch (reason) {
+ await vscode.window.showErrorMessage(`Dependency error: ${reason}`);
+ }
+ }
+ }
+ });
+ }
+
+ private shouldRevealDependency(e: vscode.TextEditor | undefined): e is RustEditor {
+ return (
+ e !== undefined &&
+ isRustEditor(e) &&
+ !isDocumentInWorkspace(e.document) &&
+ (this.treeView?.visible || false)
+ );
}
async restart() {
@@ -335,6 +406,7 @@ export class Ctx {
setServerStatus(status: ServerStatusParams | { health: "stopped" }) {
let icon = "";
const statusBar = this.statusBar;
+ statusBar.show();
statusBar.tooltip = new vscode.MarkdownString("", true);
statusBar.tooltip.isTrusted = true;
switch (status.health) {
@@ -343,6 +415,7 @@ export class Ctx {
statusBar.color = undefined;
statusBar.backgroundColor = undefined;
statusBar.command = "rust-analyzer.stopServer";
+ this.dependencies?.refresh();
break;
case "warning":
if (status.message) {
@@ -378,12 +451,17 @@ export class Ctx {
if (statusBar.tooltip.value) {
statusBar.tooltip.appendText("\n\n");
}
+ statusBar.tooltip.appendMarkdown("\n\n[Open logs](command:rust-analyzer.openLogs)");
statusBar.tooltip.appendMarkdown(
"\n\n[Reload Workspace](command:rust-analyzer.reloadWorkspace)"
);
- statusBar.tooltip.appendMarkdown("\n\n[Open logs](command:rust-analyzer.openLogs)");
- statusBar.tooltip.appendMarkdown("\n\n[Restart server](command:rust-analyzer.startServer)");
- statusBar.tooltip.appendMarkdown("[Stop server](command:rust-analyzer.stopServer)");
+ statusBar.tooltip.appendMarkdown(
+ "\n\n[Rebuild Proc Macros](command:rust-analyzer.rebuildProcMacros)"
+ );
+ statusBar.tooltip.appendMarkdown(
+ "\n\n[Restart server](command:rust-analyzer.restartServer)"
+ );
+ statusBar.tooltip.appendMarkdown("\n\n[Stop server](command:rust-analyzer.stopServer)");
if (!status.quiescent) icon = "$(sync~spin) ";
statusBar.text = `${icon}rust-analyzer`;
}
@@ -400,4 +478,5 @@ export class Ctx {
export interface Disposable {
dispose(): void;
}
+
export type Cmd = (...args: any[]) => unknown;