From 26d6827003f34a92273f551095f0b0c655a5d2be Mon Sep 17 00:00:00 2001 From: Jessica He Date: Tue, 13 Sep 2022 16:12:51 -0400 Subject: [PATCH] qute notebook --- package.json | 16 ++++++- src/extension.ts | 12 +++++ src/qute/quteNotebook/qBookController.ts | 60 ++++++++++++++++++++++++ src/qute/quteNotebook/qBookSerializer.ts | 57 ++++++++++++++++++++++ 4 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 src/qute/quteNotebook/qBookController.ts create mode 100644 src/qute/quteNotebook/qBookSerializer.ts diff --git a/package.json b/package.json index 1d6919d5..8e936582 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,9 @@ "onLanguage:qute-html", "onLanguage:qute-json", "onLanguage:qute-yaml", - "onLanguage:qute-txt" + "onLanguage:qute-txt", + "onNotebook:qbook", + "workspaceContains:**/*.qbook" ], "main": "./dist/extension", "extensionDependencies": [ @@ -397,6 +399,18 @@ "scopeName": "grammar.qute", "path": "./language-support/qute/qute.tmLanguage.json" } + ], + "notebooks": [ + { + "id": "qbook", + "type": "qbook", + "displayName": "Qute NoteBook", + "selector": [ + { + "filenamePattern": "*.qbook" + } + ] + } ] }, "scripts": { diff --git a/src/extension.ts b/src/extension.ts index cdecfa2f..843d096f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -27,6 +27,8 @@ import { initTelemetryService } from './utils/telemetryUtils'; import { getFilePathsFromWorkspace } from './utils/workspaceUtils'; import { WelcomeWebview } from './webviews/WelcomeWebview'; import { createTerminateDebugListener } from './wizards/debugging/terminateProcess'; +import { QBookSerializer } from './qute/quteNotebook/qBookSerializer'; +import { QBookController } from './qute/quteNotebook/qBookController'; // alias for vscode-java's ExtensionAPI export type JavaExtensionAPI = any; @@ -92,6 +94,7 @@ async function doActivate(context: ExtensionContext) { }); }); + registerQuteNotebook(context); } export function deactivate() { @@ -155,3 +158,12 @@ async function isQuarkusProject(): Promise { } return false; } + +function registerQuteNotebook(context: ExtensionContext) { + context.subscriptions.push( + workspace.registerNotebookSerializer( + 'qbook', new QBookSerializer(), { transientOutputs: true } + ), + new QBookController() + ); +} diff --git a/src/qute/quteNotebook/qBookController.ts b/src/qute/quteNotebook/qBookController.ts new file mode 100644 index 00000000..23b70c52 --- /dev/null +++ b/src/qute/quteNotebook/qBookController.ts @@ -0,0 +1,60 @@ +import * as vscode from 'vscode'; + +export class QBookController { + readonly id = 'test-notebook-renderer-kernel'; + public readonly label = 'Sample Notebook Kernel'; + readonly supportedLanguages = ['json', 'qute-html', 'qute-yaml', 'qute-json', 'qute-txt']; + + private _executionOrder = 0; + private readonly _controller: vscode.NotebookController; + + constructor() { + + this._controller = vscode.notebooks.createNotebookController(this.id, + 'qbook', + this.label); + + this._controller.supportedLanguages = this.supportedLanguages; + this._controller.supportsExecutionOrder = true; + this._controller.executeHandler = this._executeAll.bind(this); + } + + dispose(): void { + this._controller.dispose(); + } + + private _executeAll(cells: vscode.NotebookCell[], _notebook: vscode.NotebookDocument, _controller: vscode.NotebookController): void { + for (let cell of cells) { + this._doExecution(cell); + } + } + + private async _doExecution(cell: vscode.NotebookCell): Promise { + const execution = this._controller.createNotebookCellExecution(cell); + + const previousIndex = cell.index -1; + const previousCell = cell && cell.notebook.cellAt(previousIndex); + const data = previousCell && previousCell.document.getText(); + + execution.executionOrder = ++this._executionOrder; + execution.start(Date.now()); + + try { + + const templateContent = cell.document.getText(); + const result : string = await vscode.commands.executeCommand('qute.generate', templateContent, data ); + + execution.replaceOutput([new vscode.NotebookCellOutput([ + //vscode.NotebookCellOutputItem.text(cell.document.getText()+ data, "x-application/sample-json-renderer"), + vscode.NotebookCellOutputItem.text(result) + ])]); + + execution.end(true, Date.now()); + } catch (err) { + execution.replaceOutput([new vscode.NotebookCellOutput([ + vscode.NotebookCellOutputItem.error(err) + ])]); + execution.end(false, Date.now()); + } + } +} diff --git a/src/qute/quteNotebook/qBookSerializer.ts b/src/qute/quteNotebook/qBookSerializer.ts new file mode 100644 index 00000000..fb0a9b6a --- /dev/null +++ b/src/qute/quteNotebook/qBookSerializer.ts @@ -0,0 +1,57 @@ +import * as vscode from 'vscode'; +import { TextDecoder, TextEncoder } from "util"; + +interface RawNotebookData { + cells: RawNotebookCell[] +} + +interface RawNotebookCell { + language: string; + value: string; + kind: vscode.NotebookCellKind; + editable?: boolean; +} + +export class QBookSerializer implements vscode.NotebookSerializer { + public readonly label: string = 'My Sample Content Serializer'; + + public async deserializeNotebook(data: Uint8Array, token: vscode.CancellationToken): Promise { + var contents = new TextDecoder().decode(data); // convert to String to make JSON object + + // Read file contents + let raw: RawNotebookData; + try { + raw = JSON.parse(contents); + } catch { + raw = { cells: [] }; + } + + // Create array of Notebook cells for the VS Code API from file contents + const cells = raw.cells.map(item => new vscode.NotebookCellData( + item.kind, + item.value, + item.language + )); + + // Pass read and formatted Notebook Data to VS Code to display Notebook with saved cells + return new vscode.NotebookData( + cells + ); + } + + public async serializeNotebook(data: vscode.NotebookData, token: vscode.CancellationToken): Promise { + // Map the Notebook data into the format we want to save the Notebook data as + let contents: RawNotebookData = { cells: []}; + + for (const cell of data.cells) { + contents.cells.push({ + kind: cell.kind, + language: cell.languageId, + value: cell.value + }); + } + + // Give a string of all the data to save and VS Code will handle the rest + return new TextEncoder().encode(JSON.stringify(contents)); + } +}