Skip to content

Commit 56d06fb

Browse files
committed
Add an action to copy an element from the syntax tree view
1 parent 628db53 commit 56d06fb

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

src/tools/rust-analyzer/editors/code/package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,12 @@
289289
"icon": "$(search)",
290290
"category": "rust-analyzer (syntax tree)"
291291
},
292+
{
293+
"command": "rust-analyzer.syntaxTreeCopy",
294+
"title": "Copy",
295+
"icon": "$(copy)",
296+
"category": "rust-analyzer (syntax tree)"
297+
},
292298
{
293299
"command": "rust-analyzer.syntaxTreeHideWhitespace",
294300
"title": "Hide Whitespace",
@@ -3370,6 +3376,10 @@
33703376
"command": "rust-analyzer.syntaxTreeReveal",
33713377
"when": "false"
33723378
},
3379+
{
3380+
"command": "rust-analyzer.syntaxTreeCopy",
3381+
"when": "false"
3382+
},
33733383
{
33743384
"command": "rust-analyzer.syntaxTreeHideWhitespace",
33753385
"when": "false"
@@ -3404,6 +3414,11 @@
34043414
}
34053415
],
34063416
"view/item/context": [
3417+
{
3418+
"command": "rust-analyzer.syntaxTreeCopy",
3419+
"group": "inline",
3420+
"when": "view == rustSyntaxTree"
3421+
},
34073422
{
34083423
"command": "rust-analyzer.syntaxTreeReveal",
34093424
"group": "inline",

src/tools/rust-analyzer/editors/code/src/commands.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,45 @@ export function syntaxTreeReveal(): Cmd {
372372
};
373373
}
374374

375+
function elementToString(
376+
activeDocument: vscode.TextDocument,
377+
element: SyntaxElement,
378+
depth: number = 0,
379+
): string {
380+
let result = " ".repeat(depth);
381+
const start = element.istart ?? element.start;
382+
const end = element.iend ?? element.end;
383+
384+
result += `${element.kind}@${start}..${end}`;
385+
386+
if (element.type === "Token") {
387+
const startPosition = activeDocument.positionAt(element.start);
388+
const endPosition = activeDocument.positionAt(element.end);
389+
const text = activeDocument.getText(new vscode.Range(startPosition, endPosition));
390+
// JSON.stringify quotes and escapes the string for us.
391+
result += ` ${JSON.stringify(text)}\n`;
392+
} else {
393+
result += "\n";
394+
for (const child of element.children) {
395+
result += elementToString(activeDocument, child, depth + 1);
396+
}
397+
}
398+
399+
return result;
400+
}
401+
402+
export function syntaxTreeCopy(): Cmd {
403+
return async (element: SyntaxElement) => {
404+
const activeDocument = vscode.window.activeTextEditor?.document;
405+
if (!activeDocument) {
406+
return;
407+
}
408+
409+
const result = elementToString(activeDocument, element);
410+
await vscode.env.clipboard.writeText(result);
411+
};
412+
}
413+
375414
export function syntaxTreeHideWhitespace(ctx: CtxInit): Cmd {
376415
return async () => {
377416
if (ctx.syntaxTreeProvider !== undefined) {

src/tools/rust-analyzer/editors/code/src/main.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ function createCommands(): Record<string, CommandFactory> {
199199
openLogs: { enabled: commands.openLogs },
200200
revealDependency: { enabled: commands.revealDependency },
201201
syntaxTreeReveal: { enabled: commands.syntaxTreeReveal },
202+
syntaxTreeCopy: { enabled: commands.syntaxTreeCopy },
202203
syntaxTreeHideWhitespace: { enabled: commands.syntaxTreeHideWhitespace },
203204
syntaxTreeShowWhitespace: { enabled: commands.syntaxTreeShowWhitespace },
204205
};

0 commit comments

Comments
 (0)