]> git.lizzy.rs Git - rust.git/blob - editors/code/src/commands/expand_macro.ts
Move expand macro to the new context
[rust.git] / editors / code / src / commands / expand_macro.ts
1 import * as vscode from 'vscode';
2 import * as lc from 'vscode-languageclient';
3
4 import { Ctx, Cmd } from '../ctx';
5
6 // Opens the virtual file that will show the syntax tree
7 //
8 // The contents of the file come from the `TextDocumentContentProvider`
9 export function expandMacro(ctx: Ctx): Cmd {
10     const tdcp = new TextDocumentContentProvider(ctx);
11     ctx.pushCleanup(
12         vscode.workspace.registerTextDocumentContentProvider(
13             'rust-analyzer',
14             tdcp,
15         ),
16     );
17
18     return async () => {
19         const document = await vscode.workspace.openTextDocument(tdcp.uri);
20         tdcp.eventEmitter.fire(tdcp.uri);
21         return vscode.window.showTextDocument(
22             document,
23             vscode.ViewColumn.Two,
24             true,
25         );
26     };
27 }
28
29 interface ExpandedMacro {
30     name: string;
31     expansion: string;
32 }
33
34 function code_format(expanded: ExpandedMacro): string {
35     let result = `// Recursive expansion of ${expanded.name}! macro\n`;
36     result += '// ' + '='.repeat(result.length - 3);
37     result += '\n\n';
38     result += expanded.expansion;
39
40     return result;
41 }
42
43 class TextDocumentContentProvider
44     implements vscode.TextDocumentContentProvider {
45     private ctx: Ctx;
46     uri = vscode.Uri.parse('rust-analyzer://expandMacro/[EXPANSION].rs');
47     eventEmitter = new vscode.EventEmitter<vscode.Uri>();
48
49     constructor(ctx: Ctx) {
50         this.ctx = ctx;
51     }
52
53     async provideTextDocumentContent(_uri: vscode.Uri): Promise<string> {
54         const editor = vscode.window.activeTextEditor;
55         if (editor == null) return '';
56
57         const position = editor.selection.active;
58         const request: lc.TextDocumentPositionParams = {
59             textDocument: { uri: editor.document.uri.toString() },
60             position,
61         };
62         const expanded = await this.ctx.client.sendRequest<ExpandedMacro>(
63             'rust-analyzer/expandMacro',
64             request,
65         );
66
67         if (expanded == null) return 'Not available';
68
69         return code_format(expanded);
70     }
71
72     get onDidChange(): vscode.Event<vscode.Uri> {
73         return this.eventEmitter.event;
74     }
75 }