about summary refs log tree commit diff
path: root/editors/code/src
diff options
context:
space:
mode:
Diffstat (limited to 'editors/code/src')
-rw-r--r--editors/code/src/commands/expand_macro.ts83
-rw-r--r--editors/code/src/commands/index.ts2
-rw-r--r--editors/code/src/extension.ts12
3 files changed, 97 insertions, 0 deletions
diff --git a/editors/code/src/commands/expand_macro.ts b/editors/code/src/commands/expand_macro.ts
new file mode 100644
index 00000000000..34e0c8fb337
--- /dev/null
+++ b/editors/code/src/commands/expand_macro.ts
@@ -0,0 +1,83 @@
+import * as vscode from 'vscode';
+import { Position, TextDocumentIdentifier } from 'vscode-languageclient';
+import { Server } from '../server';
+
+export const expandMacroUri = vscode.Uri.parse(
+    'rust-analyzer://expandMacro/[EXPANSION].rs'
+);
+
+export class ExpandMacroContentProvider
+    implements vscode.TextDocumentContentProvider {
+    public eventEmitter = new vscode.EventEmitter<vscode.Uri>();
+
+    public provideTextDocumentContent(
+        uri: vscode.Uri
+    ): vscode.ProviderResult<string> {
+        async function handle() {
+            const editor = vscode.window.activeTextEditor;
+            if (editor == null) {
+                return '';
+            }
+
+            const position = editor.selection.active;
+            const request: MacroExpandParams = {
+                textDocument: { uri: editor.document.uri.toString() },
+                position
+            };
+            const expanded = await Server.client.sendRequest<ExpandedMacro>(
+                'rust-analyzer/expandMacro',
+                request
+            );
+
+            if (expanded == null) {
+                return 'Not available';
+            }
+
+            return code_format(expanded);
+        }
+
+        return handle();
+    }
+
+    get onDidChange(): vscode.Event<vscode.Uri> {
+        return this.eventEmitter.event;
+    }
+}
+
+// Opens the virtual file that will show the syntax tree
+//
+// The contents of the file come from the `TextDocumentContentProvider`
+export function createHandle(provider: ExpandMacroContentProvider) {
+    return async () => {
+        const uri = expandMacroUri;
+
+        const document = await vscode.workspace.openTextDocument(uri);
+
+        provider.eventEmitter.fire(uri);
+
+        return vscode.window.showTextDocument(
+            document,
+            vscode.ViewColumn.Two,
+            true
+        );
+    };
+}
+
+interface MacroExpandParams {
+    textDocument: TextDocumentIdentifier;
+    position: Position;
+}
+
+interface ExpandedMacro {
+    name: string;
+    expansion: string;
+}
+
+function code_format(expanded: ExpandedMacro): string {
+    let result = `// Recursive expansion of ${expanded.name}! macro\n`;
+    result += '// ' + '='.repeat(result.length - 3);
+    result += '\n\n';
+    result += expanded.expansion;
+
+    return result;
+}
diff --git a/editors/code/src/commands/index.ts b/editors/code/src/commands/index.ts
index c194bd2eacc..2ade6d331a7 100644
--- a/editors/code/src/commands/index.ts
+++ b/editors/code/src/commands/index.ts
@@ -1,5 +1,6 @@
 import * as analyzerStatus from './analyzer_status';
 import * as applySourceChange from './apply_source_change';
+import * as expandMacro from './expand_macro';
 import * as inlayHints from './inlay_hints';
 import * as joinLines from './join_lines';
 import * as matchingBrace from './matching_brace';
@@ -11,6 +12,7 @@ import * as syntaxTree from './syntaxTree';
 export {
     analyzerStatus,
     applySourceChange,
+    expandMacro,
     joinLines,
     matchingBrace,
     parentModule,
diff --git a/editors/code/src/extension.ts b/editors/code/src/extension.ts
index c06928d122b..683497dfd4d 100644
--- a/editors/code/src/extension.ts
+++ b/editors/code/src/extension.ts
@@ -3,6 +3,7 @@ import * as lc from 'vscode-languageclient';
 
 import * as commands from './commands';
 import { CargoWatchProvider } from './commands/cargo_watch';
+import { ExpandMacroContentProvider } from './commands/expand_macro';
 import { HintsUpdater } from './commands/inlay_hints';
 import {
     interactivelyStartCargoWatch,
@@ -97,6 +98,7 @@ export function activate(context: vscode.ExtensionContext) {
         ]
     ];
     const syntaxTreeContentProvider = new SyntaxTreeContentProvider();
+    const expandMacroContentProvider = new ExpandMacroContentProvider();
 
     // The events below are plain old javascript events, triggered and handled by vscode
     vscode.window.onDidChangeActiveTextEditor(
@@ -109,11 +111,21 @@ export function activate(context: vscode.ExtensionContext) {
             syntaxTreeContentProvider
         )
     );
+    disposeOnDeactivation(
+        vscode.workspace.registerTextDocumentContentProvider(
+            'rust-analyzer',
+            expandMacroContentProvider
+        )
+    );
 
     registerCommand(
         'rust-analyzer.syntaxTree',
         commands.syntaxTree.createHandle(syntaxTreeContentProvider)
     );
+    registerCommand(
+        'rust-analyzer.expandMacro',
+        commands.expandMacro.createHandle(expandMacroContentProvider)
+    );
 
     vscode.workspace.onDidChangeTextDocument(
         events.changeTextDocument.createHandler(syntaxTreeContentProvider),