Unnamed repository; edit this file 'description' to name the repository.
Add an action to copy an element from the syntax tree view
Giga Bowser 2025-01-10
parent cb5ce9e · commit c0f22c7
-rw-r--r--editors/code/package.json15
-rw-r--r--editors/code/src/commands.ts39
-rw-r--r--editors/code/src/main.ts1
3 files changed, 55 insertions, 0 deletions
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
@@ -290,6 +290,12 @@
"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",
"icon": "$(filter)",
@@ -3371,6 +3377,10 @@
"when": "false"
},
{
+ "command": "rust-analyzer.syntaxTreeCopy",
+ "when": "false"
+ },
+ {
"command": "rust-analyzer.syntaxTreeHideWhitespace",
"when": "false"
},
@@ -3405,6 +3415,11 @@
],
"view/item/context": [
{
+ "command": "rust-analyzer.syntaxTreeCopy",
+ "group": "inline",
+ "when": "view == rustSyntaxTree"
+ },
+ {
"command": "rust-analyzer.syntaxTreeReveal",
"group": "inline",
"when": "view == rustSyntaxTree"
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<string, CommandFactory> {
openLogs: { enabled: commands.openLogs },
revealDependency: { enabled: commands.revealDependency },
syntaxTreeReveal: { enabled: commands.syntaxTreeReveal },
+ syntaxTreeCopy: { enabled: commands.syntaxTreeCopy },
syntaxTreeHideWhitespace: { enabled: commands.syntaxTreeHideWhitespace },
syntaxTreeShowWhitespace: { enabled: commands.syntaxTreeShowWhitespace },
};