Skip to content

Commit 432256d

Browse files
committed
App Engine API
1 parent f680b15 commit 432256d

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed

package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@
3232
"command": "plutoEditor.openCurrentWith",
3333
"title": "Open with Pluto.jl 🎈",
3434
"category": "Pluto"
35+
},
36+
{
37+
"command": "plutoAppEngine.newNotebook",
38+
"title": "Pluto.jl app engine: empty notebook",
39+
"category": "Pluto"
40+
},
41+
{
42+
"command": "plutoAppEngine.openCurrentWith",
43+
"title": "Pluto.jl app engine: open file as app",
44+
"category": "Pluto"
3545
}
3646
],
3747
"customEditors": [

src/app_engine.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import * as vscode from "vscode"
2+
import { v4 as uuid } from "uuid"
3+
import { setup_pluto_in_webview, getWebviewOptions } from "./setup_webview"
4+
import { get_default_backend } from "./backend"
5+
import { LOADING_HTML, empty_notebook_contents } from "./extension"
6+
7+
const viewType = "plutoEditor"
8+
9+
export const start_empty_notebook_app = (context: vscode.ExtensionContext, args: { disable_ui?: boolean } = {}) => {
10+
return start_notebook_file_app(context, {
11+
notebook_file_contents: empty_notebook_contents(),
12+
...args,
13+
})
14+
}
15+
16+
export const start_notebook_file_app = (
17+
context: vscode.ExtensionContext,
18+
args: { notebook_file_contents: string; disable_ui?: boolean; isolated_cell_ids?: string[] }
19+
) => {
20+
const { notebook_file_contents, disable_ui, isolated_cell_ids } = args
21+
22+
start_app_engine(context, {
23+
notebook_file_contents,
24+
frontend_params: {
25+
disable_ui: disable_ui ? disable_ui : undefined,
26+
isolated_cell_ids_js: isolated_cell_ids ? JSON.stringify(isolated_cell_ids) : undefined,
27+
},
28+
})
29+
}
30+
31+
/**
32+
* Start running a new notebook, create a new panel, set up the WebSocket proxy, show the notebook in the panel.
33+
*/
34+
const start_app_engine = (context: vscode.ExtensionContext, args: { notebook_file_contents: string; frontend_params?: Object }) => {
35+
console.info("Launching Pluto panel!")
36+
37+
/** Where should the panel appear? */
38+
const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined
39+
40+
// Create a new panel. This `WebviewPanel` object has lots of functionality, see https://code.visualstudio.com/api/references/vscode-api#WebviewPanel and the `.webview` property: https://code.visualstudio.com/api/references/vscode-api#Webview
41+
const panel = vscode.window.createWebviewPanel(viewType, "Loading Pluto...", column || vscode.ViewColumn.One, getWebviewOptions(context.extensionUri))
42+
43+
/**
44+
* VS Code has the concept of `Disposable`, which is a resource/process/something that needs to be disposed when no longer used. We create an array `disposables` of things that need to be disposed when this window is closed.
45+
*/
46+
let disposables: vscode.Disposable[] = [panel]
47+
let disposed: boolean = false
48+
49+
panel.onDidDispose(() => {
50+
console.log("disposing!")
51+
disposed = true
52+
// Clean up our resources
53+
disposables.forEach((x) => x.dispose())
54+
})
55+
56+
/** Set the HTML content of the Webview panel. Triggers a refresh of the iframe. */
57+
const set_html = (title: string, notebook_file_contents: string) => {
58+
panel.title = title
59+
panel.webview.html = notebook_file_contents
60+
}
61+
62+
// Set the webview's initial html content
63+
set_html("Loading Pluto...", LOADING_HTML)
64+
65+
// Start creating a `backend`, i.e. start running the `julia-runtime/run.jl` script.
66+
const backend = get_default_backend(context.extensionPath)
67+
68+
const notebook_id = uuid()
69+
const editor_html_filename = `editor_bespoke_${notebook_id}.html`
70+
const jlfile = `editor_bespoke_${notebook_id}.jl`
71+
72+
console.log("frontend params: ", args.frontend_params ?? {})
73+
setup_pluto_in_webview({
74+
panel,
75+
context,
76+
notebook_id,
77+
editor_html_filename,
78+
renderStatusBar: () => {}, // TODO
79+
backend,
80+
initialize_notebook: async (extra_details: Object) => {
81+
await backend.send_command("open", {
82+
editor_html_filename,
83+
notebook_id,
84+
text: args.notebook_file_contents,
85+
jlfile,
86+
frontend_params: args.frontend_params ?? {},
87+
...extra_details,
88+
})
89+
},
90+
})
91+
}

src/extension.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from "vscode"
22
import { PlutoBackend } from "./backend"
33
import { PlutoEditor } from "./PlutoEditor"
4+
import { start_empty_notebook_app, start_notebook_file_app } from "./app_engine"
45
import { TextDecoder, TextEncoder } from "util"
56
import { v4 as uuid } from "uuid"
67

@@ -70,6 +71,39 @@ export function activate(context: vscode.ExtensionContext) {
7071
vscode.commands.executeCommand("vscode.openWith", selectedDocumentURI, "plutoEditor")
7172
})
7273
)
74+
context.subscriptions.push(
75+
vscode.commands.registerCommand("plutoAppEngine.newNotebook", () => {
76+
start_empty_notebook_app(context)
77+
})
78+
)
79+
context.subscriptions.push(
80+
vscode.commands.registerCommand("plutoAppEngine.openNotebook", async (documentURI, isolated_cell_ids = undefined) => {
81+
start_notebook_file_app(context, {
82+
notebook_file_contents: new TextDecoder().decode(await vscode.workspace.fs.readFile(documentURI)),
83+
isolated_cell_ids: isolated_cell_ids,
84+
})
85+
})
86+
)
87+
88+
/** This will be available as our `.exports` when this extension is used by another extension, see https://code.visualstudio.com/api/references/vscode-api#extensions. */
89+
const api = {
90+
version: 1,
91+
runNotebookApp: (args: { notebook_file_contents: string; isolated_cell_ids?: string[]; disable_ui?: boolean; [_ignored: string]: any }) =>
92+
start_notebook_file_app(context, args),
93+
}
94+
95+
// let cool_nb =
96+
// '### A Pluto.jl notebook ###\n# v0.17.1\n\nusing Markdown\nusing InteractiveUtils\n\n# ╔═╡ 3d0fb1de-8e96-4eed-8563-c91de4786001\n"show me!!!"\n\n# ╔═╡ 3d0fb1de-8e96-4eed-8563-c91de4786002\ndont\' show me\n\n# ╔═╡ Cell order:\n# ╠═3d0fb1de-8e96-4eed-8563-c91de4786001\n# ╠═3d0fb1de-8e96-4eed-8563-c91de4786002'
97+
98+
// let cool_nb_cell_id = "3d0fb1de-8e96-4eed-8563-c91de4786001"
99+
100+
// api.runNotebookApp({
101+
// notebook_file_contents: cool_nb,
102+
// isolated_cell_ids: [cool_nb_cell_id],
103+
// disable_ui: true,
104+
// })
105+
106+
return api
73107
}
74108

75109
export const LOADING_HTML = `<!DOCTYPE html>

0 commit comments

Comments
 (0)