From c0f22c7e9dcb76e90f17d5bcce1fb8496f8409ed Mon Sep 17 00:00:00 2001 From: Giga Bowser <45986823+Giga-Bowser@users.noreply.github.com> Date: Tue, 7 Jan 2025 14:01:00 -0600 Subject: [PATCH] Add an action to copy an element from the syntax tree view --- editors/code/package.json | 15 ++++++++++++++ editors/code/src/commands.ts | 39 ++++++++++++++++++++++++++++++++++++ editors/code/src/main.ts | 1 + 3 files changed, 55 insertions(+) diff --git a/editors/code/package.json b/editors/code/package.json index 6deb5bfd77..6900719454 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -289,6 +289,12 @@ "icon": "$(search)", "category": "rust-analyzer (syntax tree)" }, + { + "command": "rust-analyzer.syntaxTreeCopy", + "title": "Copy", + "icon": "$(copy)", + "category": "rust-analyzer (syntax tree)" + }, { "command": "rust-analyzer.syntaxTreeHideWhitespace", "title": "Hide Whitespace", @@ -3370,6 +3376,10 @@ "command": "rust-analyzer.syntaxTreeReveal", "when": "false" }, + { + "command": "rust-analyzer.syntaxTreeCopy", + "when": "false" + }, { "command": "rust-analyzer.syntaxTreeHideWhitespace", "when": "false" @@ -3404,6 +3414,11 @@ } ], "view/item/context": [ + { + "command": "rust-analyzer.syntaxTreeCopy", + "group": "inline", + "when": "view == rustSyntaxTree" + }, { "command": "rust-analyzer.syntaxTreeReveal", "group": "inline", diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts index f94c57eee8..b3aa04af7e 100644 --- a/editors/code/src/commands.ts +++ b/editors/code/src/commands.ts @@ -372,6 +372,45 @@ export function syntaxTreeReveal(): Cmd { }; } +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) { diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index 59c131cb37..c84b69b66c 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -199,6 +199,7 @@ function createCommands(): Record { openLogs: { enabled: commands.openLogs }, revealDependency: { enabled: commands.revealDependency }, syntaxTreeReveal: { enabled: commands.syntaxTreeReveal }, + syntaxTreeCopy: { enabled: commands.syntaxTreeCopy }, syntaxTreeHideWhitespace: { enabled: commands.syntaxTreeHideWhitespace }, syntaxTreeShowWhitespace: { enabled: commands.syntaxTreeShowWhitespace }, };