113 lines
4.0 KiB
TypeScript
113 lines
4.0 KiB
TypeScript
import * as vscode from 'vscode';
|
|
import init, * as dioxus from 'dioxus-ext';
|
|
|
|
export async function activate(context: vscode.ExtensionContext) {
|
|
// Load the wasm from the file system
|
|
const wasmSourceCode = await vscode.workspace.fs.readFile(vscode.Uri.joinPath(context.extensionUri, "./pkg/dioxus_ext_bg.wasm"));
|
|
|
|
// Wait for the initialization to finish
|
|
// This is using the byte buffer directly which won't go through the "fetch" machinery
|
|
//
|
|
// For whatever reason, wasm-bindgen generates `fetch` when we don't want it to
|
|
// VSCode doesn't have a `fetch` implementation, but we don't really care about polyfilling it
|
|
await init(wasmSourceCode);
|
|
|
|
// Todo:
|
|
// I want a paste-handler that translates HTML to RSX whenever HTML is pasted into an Rsx block
|
|
// Or, a little tooltip that pops up and asks if you want to translate the HTML to RSX
|
|
context.subscriptions.push(
|
|
vscode.commands.registerCommand('extension.htmlToDioxusRsx', () => translate(false)),
|
|
vscode.commands.registerCommand('extension.htmlToDioxusComponent', () => translate(true)),
|
|
vscode.commands.registerCommand('extension.formatRsx', fmtSelection),
|
|
vscode.commands.registerCommand('extension.formatRsxDocument', formatRsxDocument),
|
|
vscode.workspace.onWillSaveTextDocument(fmtDocumentOnSave)
|
|
);
|
|
}
|
|
|
|
function translate(component: boolean) {
|
|
// Load the activate editor
|
|
const editor = vscode.window.activeTextEditor;
|
|
if (!editor) return;
|
|
|
|
// Get the selected text
|
|
const html = editor.document.getText(editor.selection);
|
|
if (html.length == 0) {
|
|
vscode.window.showWarningMessage("Please select HTML fragment before invoking this command!");
|
|
return;
|
|
}
|
|
|
|
// Translate the HTML to RSX
|
|
const out = dioxus.translate_rsx(html, component);
|
|
if (out.length > 0) {
|
|
editor.edit(editBuilder => editBuilder.replace(editor.selection, out));
|
|
} else {
|
|
vscode.window.showWarningMessage(`Errors occurred while translating, make sure this block of HTML is valid`);
|
|
}
|
|
}
|
|
|
|
|
|
function formatRsxDocument() {
|
|
const editor = vscode.window.activeTextEditor;
|
|
if (!editor) return;
|
|
|
|
fmtDocument(editor.document);
|
|
}
|
|
|
|
function fmtSelection() {
|
|
const editor = vscode.window.activeTextEditor;
|
|
if (!editor) return;
|
|
|
|
const unformatted = editor.document.getText(editor.selection);
|
|
|
|
if (unformatted.length == 0) {
|
|
vscode.window.showWarningMessage("Please select rsx invoking this command!");
|
|
return;
|
|
}
|
|
|
|
const fileDir = editor.document.fileName.slice(0, editor.document.fileName.lastIndexOf('\\'));
|
|
|
|
}
|
|
|
|
function fmtDocumentOnSave(e: vscode.TextDocumentWillSaveEvent) {
|
|
// check the settings to make sure format on save is configured
|
|
const dioxusConfig = vscode.workspace.getConfiguration('dioxus', e.document).get('formatOnSave');
|
|
const globalConfig = vscode.workspace.getConfiguration('editor', e.document).get('formatOnSave');
|
|
if (
|
|
(dioxusConfig === 'enabled') ||
|
|
(dioxusConfig !== 'disabled' && globalConfig)
|
|
) {
|
|
fmtDocument(e.document);
|
|
}
|
|
}
|
|
|
|
function fmtDocument(document: vscode.TextDocument) {
|
|
try {
|
|
if (document.languageId !== "rust" || document.uri.scheme !== "file") {
|
|
return;
|
|
}
|
|
|
|
const [editor,] = vscode.window.visibleTextEditors.filter(editor => editor.document.fileName === document.fileName);
|
|
if (!editor) return; // Need an editor to apply text edits.
|
|
|
|
const contents = editor.document.getText();
|
|
let tabSize: number;
|
|
if (typeof editor.options.tabSize === 'number') {
|
|
tabSize = editor.options.tabSize;
|
|
} else {
|
|
tabSize = 4;
|
|
}
|
|
const formatted = dioxus.format_file(contents, !editor.options.insertSpaces, tabSize);
|
|
|
|
// Replace the entire text document
|
|
// Yes, this is a bit heavy handed, but the dioxus side doesn't know the line/col scheme that vscode is using
|
|
if (formatted.length() > 0) {
|
|
editor.edit(editBuilder => {
|
|
const range = new vscode.Range(0, 0, document.lineCount, 0);
|
|
editBuilder.replace(range, formatted.formatted());
|
|
});
|
|
}
|
|
} catch (error) {
|
|
vscode.window.showWarningMessage(`Errors occurred while formatting. Make sure you have the most recent Dioxus-CLI installed! \n${error}`);
|
|
}
|
|
}
|