Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'editors/code/src/commands.ts')
-rw-r--r--editors/code/src/commands.ts167
1 files changed, 77 insertions, 90 deletions
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index 73e39c900e..b3aa04af7e 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -15,7 +15,6 @@ import {
createTaskFromRunnable,
createCargoArgs,
} from "./run";
-import { AstInspector } from "./ast_inspector";
import {
isRustDocument,
isCargoRunnableArgs,
@@ -31,8 +30,8 @@ import type { LanguageClient } from "vscode-languageclient/node";
import { HOVER_REFERENCE_COMMAND } from "./client";
import type { DependencyId } from "./dependencies_provider";
import { log } from "./util";
+import type { SyntaxElement } from "./syntax_tree_provider";
-export * from "./ast_inspector";
export * from "./run";
export function analyzerStatus(ctx: CtxInit): Cmd {
@@ -288,13 +287,13 @@ export function openCargoToml(ctx: CtxInit): Cmd {
export function revealDependency(ctx: CtxInit): Cmd {
return async (editor: RustEditor) => {
- if (!ctx.dependencies?.isInitialized()) {
+ if (!ctx.dependenciesProvider?.isInitialized()) {
return;
}
const documentPath = editor.document.uri.fsPath;
- const dep = ctx.dependencies?.getDependency(documentPath);
+ const dep = ctx.dependenciesProvider?.getDependency(documentPath);
if (dep) {
- await ctx.treeView?.reveal(dep, { select: true, expand: true });
+ await ctx.dependencyTreeView?.reveal(dep, { select: true, expand: true });
} else {
await revealParentChain(editor.document, ctx);
}
@@ -340,10 +339,10 @@ async function revealParentChain(document: RustDocument, ctx: CtxInit) {
// a open file referencing the old version
return;
}
- } while (!ctx.dependencies?.contains(documentPath));
+ } while (!ctx.dependenciesProvider?.contains(documentPath));
parentChain.reverse();
for (const idx in parentChain) {
- const treeView = ctx.treeView;
+ const treeView = ctx.dependencyTreeView;
if (!treeView) {
continue;
}
@@ -357,6 +356,77 @@ export async function execRevealDependency(e: RustEditor): Promise<void> {
await vscode.commands.executeCommand("rust-analyzer.revealDependency", e);
}
+export function syntaxTreeReveal(): Cmd {
+ return async (element: SyntaxElement) => {
+ const activeEditor = vscode.window.activeTextEditor;
+
+ if (activeEditor !== undefined) {
+ const start = activeEditor.document.positionAt(element.start);
+ const end = activeEditor.document.positionAt(element.end);
+
+ const newSelection = new vscode.Selection(start, end);
+
+ activeEditor.selection = newSelection;
+ activeEditor.revealRange(newSelection);
+ }
+ };
+}
+
+function elementToString(
+ activeDocument: vscode.TextDocument,
+ element: SyntaxElement,
+ depth: number = 0,
+): string {
+ let result = " ".repeat(depth);
+ const start = element.istart ?? element.start;
+ const end = element.iend ?? element.end;
+
+ result += `${element.kind}@${start}..${end}`;
+
+ if (element.type === "Token") {
+ const startPosition = activeDocument.positionAt(element.start);
+ const endPosition = activeDocument.positionAt(element.end);
+ const text = activeDocument.getText(new vscode.Range(startPosition, endPosition));
+ // JSON.stringify quotes and escapes the string for us.
+ result += ` ${JSON.stringify(text)}\n`;
+ } else {
+ result += "\n";
+ for (const child of element.children) {
+ result += elementToString(activeDocument, child, depth + 1);
+ }
+ }
+
+ return result;
+}
+
+export function syntaxTreeCopy(): Cmd {
+ return async (element: SyntaxElement) => {
+ const activeDocument = vscode.window.activeTextEditor?.document;
+ if (!activeDocument) {
+ return;
+ }
+
+ const result = elementToString(activeDocument, element);
+ await vscode.env.clipboard.writeText(result);
+ };
+}
+
+export function syntaxTreeHideWhitespace(ctx: CtxInit): Cmd {
+ return async () => {
+ if (ctx.syntaxTreeProvider !== undefined) {
+ await ctx.syntaxTreeProvider.toggleWhitespace();
+ }
+ };
+}
+
+export function syntaxTreeShowWhitespace(ctx: CtxInit): Cmd {
+ return async () => {
+ if (ctx.syntaxTreeProvider !== undefined) {
+ await ctx.syntaxTreeProvider.toggleWhitespace();
+ }
+ };
+}
+
export function ssr(ctx: CtxInit): Cmd {
return async () => {
const editor = vscode.window.activeTextEditor;
@@ -426,89 +496,6 @@ export function serverVersion(ctx: CtxInit): Cmd {
};
}
-// Opens the virtual file that will show the syntax tree
-//
-// The contents of the file come from the `TextDocumentContentProvider`
-export function syntaxTree(ctx: CtxInit): Cmd {
- const tdcp = new (class implements vscode.TextDocumentContentProvider {
- readonly uri = vscode.Uri.parse("rust-analyzer-syntax-tree://syntaxtree/tree.rast");
- readonly eventEmitter = new vscode.EventEmitter<vscode.Uri>();
- constructor() {
- vscode.workspace.onDidChangeTextDocument(
- this.onDidChangeTextDocument,
- this,
- ctx.subscriptions,
- );
- vscode.window.onDidChangeActiveTextEditor(
- this.onDidChangeActiveTextEditor,
- this,
- ctx.subscriptions,
- );
- }
-
- private onDidChangeTextDocument(event: vscode.TextDocumentChangeEvent) {
- if (isRustDocument(event.document)) {
- // We need to order this after language server updates, but there's no API for that.
- // Hence, good old sleep().
- void sleep(10).then(() => this.eventEmitter.fire(this.uri));
- }
- }
- private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
- if (editor && isRustEditor(editor)) {
- this.eventEmitter.fire(this.uri);
- }
- }
-
- async provideTextDocumentContent(
- uri: vscode.Uri,
- ct: vscode.CancellationToken,
- ): Promise<string> {
- const rustEditor = ctx.activeRustEditor;
- if (!rustEditor) return "";
- const client = ctx.client;
-
- // When the range based query is enabled we take the range of the selection
- const range =
- uri.query === "range=true" && !rustEditor.selection.isEmpty
- ? client.code2ProtocolConverter.asRange(rustEditor.selection)
- : null;
-
- const params = { textDocument: { uri: rustEditor.document.uri.toString() }, range };
- return client.sendRequest(ra.syntaxTree, params, ct);
- }
-
- get onDidChange(): vscode.Event<vscode.Uri> {
- return this.eventEmitter.event;
- }
- })();
-
- ctx.pushExtCleanup(new AstInspector(ctx));
- ctx.pushExtCleanup(
- vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-syntax-tree", tdcp),
- );
- ctx.pushExtCleanup(
- vscode.languages.setLanguageConfiguration("ra_syntax_tree", {
- brackets: [["[", ")"]],
- }),
- );
-
- return async () => {
- const editor = vscode.window.activeTextEditor;
- const rangeEnabled = !!editor && !editor.selection.isEmpty;
-
- const uri = rangeEnabled ? vscode.Uri.parse(`${tdcp.uri.toString()}?range=true`) : tdcp.uri;
-
- const document = await vscode.workspace.openTextDocument(uri);
-
- tdcp.eventEmitter.fire(uri);
-
- void (await vscode.window.showTextDocument(document, {
- viewColumn: vscode.ViewColumn.Two,
- preserveFocus: true,
- }));
- };
-}
-
function viewHirOrMir(ctx: CtxInit, xir: "hir" | "mir"): Cmd {
const viewXir = xir === "hir" ? "viewHir" : "viewMir";
const requestType = xir === "hir" ? ra.viewHir : ra.viewMir;