import { Position, TextDocumentIdentifier } from 'vscode-languageclient';
import { Server } from '../server';
-interface ExpandedMacro {
- name: string,
- expansion: string,
-}
+export const expandMacroUri = vscode.Uri.parse(
+ 'rust-analyzer://expandMacro/[EXPANSION].rs'
+);
-function code_format(expanded: ExpandedMacro): vscode.MarkdownString {
- const markdown = new vscode.MarkdownString(
- `#### Recursive expansion of ${expanded.name}! macro`
- );
- markdown.appendCodeblock(expanded.expansion, 'rust');
- return markdown;
-}
+export class ExpandMacroContentProvider
+ implements vscode.TextDocumentContentProvider {
+ public eventEmitter = new vscode.EventEmitter<vscode.Uri>();
-export class ExpandMacroHoverProvider implements vscode.HoverProvider {
- public provideHover(
- document: vscode.TextDocument,
- position: vscode.Position,
- token: vscode.CancellationToken
- ): Thenable<vscode.Hover | null> | null {
+ 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: document.uri.toString() },
+ textDocument: { uri: editor.document.uri.toString() },
position
};
- const result = await Server.client.sendRequest<ExpandedMacro>(
+ const expanded = await Server.client.sendRequest<ExpandedMacro>(
'rust-analyzer/expandMacro',
request
);
- if (result != null) {
- const formated = code_format(result);
- return new vscode.Hover(formated);
+
+ if (expanded == null) {
+ return 'Not available';
}
- return null;
+ 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);
+ result += '\n\n';
+ result += expanded.expansion;
+
+ return result;
+}
import * as commands from './commands';
import { CargoWatchProvider } from './commands/cargo_watch';
-import { ExpandMacroHoverProvider } from './commands/expand_macro';
+import { ExpandMacroContentProvider } from './commands/expand_macro';
import { HintsUpdater } from './commands/inlay_hints';
import {
interactivelyStartCargoWatch,
]
];
const syntaxTreeContentProvider = new SyntaxTreeContentProvider();
+ const expandMacroContentProvider = new ExpandMacroContentProvider();
// The events below are plain old javascript events, triggered and handled by vscode
vscode.window.onDidChangeActiveTextEditor(
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),
context.subscriptions
);
- const expandMacroContentProvider = new ExpandMacroHoverProvider();
-
- disposeOnDeactivation(
- vscode.languages.registerHoverProvider(
- 'rust',
- expandMacroContentProvider
- )
- );
-
const startServer = () => Server.start(allNotifications);
const reloadCommand = () => reloadServer(startServer);