Add an action to copy an element from the syntax tree view

This commit is contained in:
Giga Bowser 2025-01-07 14:01:00 -06:00
parent cb5ce9eaa6
commit c0f22c7e9d
3 changed files with 55 additions and 0 deletions

View file

@ -289,6 +289,12 @@
"icon": "$(search)", "icon": "$(search)",
"category": "rust-analyzer (syntax tree)" "category": "rust-analyzer (syntax tree)"
}, },
{
"command": "rust-analyzer.syntaxTreeCopy",
"title": "Copy",
"icon": "$(copy)",
"category": "rust-analyzer (syntax tree)"
},
{ {
"command": "rust-analyzer.syntaxTreeHideWhitespace", "command": "rust-analyzer.syntaxTreeHideWhitespace",
"title": "Hide Whitespace", "title": "Hide Whitespace",
@ -3370,6 +3376,10 @@
"command": "rust-analyzer.syntaxTreeReveal", "command": "rust-analyzer.syntaxTreeReveal",
"when": "false" "when": "false"
}, },
{
"command": "rust-analyzer.syntaxTreeCopy",
"when": "false"
},
{ {
"command": "rust-analyzer.syntaxTreeHideWhitespace", "command": "rust-analyzer.syntaxTreeHideWhitespace",
"when": "false" "when": "false"
@ -3404,6 +3414,11 @@
} }
], ],
"view/item/context": [ "view/item/context": [
{
"command": "rust-analyzer.syntaxTreeCopy",
"group": "inline",
"when": "view == rustSyntaxTree"
},
{ {
"command": "rust-analyzer.syntaxTreeReveal", "command": "rust-analyzer.syntaxTreeReveal",
"group": "inline", "group": "inline",

View file

@ -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 { export function syntaxTreeHideWhitespace(ctx: CtxInit): Cmd {
return async () => { return async () => {
if (ctx.syntaxTreeProvider !== undefined) { if (ctx.syntaxTreeProvider !== undefined) {

View file

@ -199,6 +199,7 @@ function createCommands(): Record<string, CommandFactory> {
openLogs: { enabled: commands.openLogs }, openLogs: { enabled: commands.openLogs },
revealDependency: { enabled: commands.revealDependency }, revealDependency: { enabled: commands.revealDependency },
syntaxTreeReveal: { enabled: commands.syntaxTreeReveal }, syntaxTreeReveal: { enabled: commands.syntaxTreeReveal },
syntaxTreeCopy: { enabled: commands.syntaxTreeCopy },
syntaxTreeHideWhitespace: { enabled: commands.syntaxTreeHideWhitespace }, syntaxTreeHideWhitespace: { enabled: commands.syntaxTreeHideWhitespace },
syntaxTreeShowWhitespace: { enabled: commands.syntaxTreeShowWhitespace }, syntaxTreeShowWhitespace: { enabled: commands.syntaxTreeShowWhitespace },
}; };