From 5e45131861678beb0a473e24cebcc43528410423 Mon Sep 17 00:00:00 2001 From: Konstantinos Kaloutas Date: Wed, 24 Jul 2024 14:23:01 +0300 Subject: [PATCH] test python repl using pyodide --- package-lock.json | 36 +++++++++++++++++++++++++++++- package.json | 3 ++- src/electron/preload.cljs | 7 +++++- src/renderer/reepl/codemirror.cljs | 1 + src/renderer/reepl/core.cljs | 4 +++- src/renderer/reepl/replumb.cljs | 15 ++++++++----- src/renderer/reepl/views.cljs | 15 +++++++++---- 7 files changed, 67 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index 492ffc86..972ae449 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,8 @@ "electron-window-state": "5.0.3", "font-scanner": "0.2.1", "mdn-data": "2.8.0", - "opentype.js": "1.3.4" + "opentype.js": "1.3.4", + "pyodide": "0.26.1" }, "devDependencies": { "@mdn/browser-compat-data": "5.5.40", @@ -9977,6 +9978,39 @@ "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", "dev": true }, + "node_modules/pyodide": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/pyodide/-/pyodide-0.26.1.tgz", + "integrity": "sha512-P+Gm88nwZqY7uBgjbQH8CqqU6Ei/rDn7pS1t02sNZsbyLJMyE2OVXjgNuqVT3KqYWnyGREUN0DbBUCJqk8R0ew==", + "license": "Apache-2.0", + "dependencies": { + "ws": "^8.5.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/pyodide/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/qjobs": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", diff --git a/package.json b/package.json index 1e1b871f..0f9f5f84 100644 --- a/package.json +++ b/package.json @@ -125,6 +125,7 @@ "electron-window-state": "5.0.3", "font-scanner": "0.2.1", "mdn-data": "2.8.0", - "opentype.js": "1.3.4" + "opentype.js": "1.3.4", + "pyodide": "0.26.1" } } diff --git a/src/electron/preload.cljs b/src/electron/preload.cljs index 9d5a7632..cc7c9e17 100644 --- a/src/electron/preload.cljs +++ b/src/electron/preload.cljs @@ -7,8 +7,11 @@ ["mdn-data" :as mdn] ;; deprecating in favor of w3c/webref ["opentype.js" :as opentype] ["os" :as os] + ["pyodide" :refer [loadPyodide]] [config])) +(def pyodide (atom nil)) + (defn text->path "https://github.com/opentypejs/opentype.js#loading-a-font-synchronously-nodejs" [text {:keys [font-url x y font-size]}] @@ -21,6 +24,7 @@ :receive (fn [channel f] ;; Strip event (_) as it includes `sender` (.on ipcRenderer channel (fn [_ args] (f args)))) + :runPython #(.runPython ^js @pyodide %) :mdn mdn :webrefCss css :platform (.platform os) @@ -33,7 +37,8 @@ (defn ^:export init [] ;; https://docs.sentry.io/platforms/javascript/guides/electron/#configuring-the-client #_(.init Sentry (clj->js config/sentry-options)) - ;; Expose protected methods that allow the renderer process to use the + (.then (loadPyodide) #(reset! pyodide %)) + ;; Expose protected methods that allow the renderer process to use the ;; ipcRenderer without exposing the entire object ;; https://www.electronjs.org/docs/api/context-bridge (.exposeInMainWorld contextBridge "api" (clj->js api))) diff --git a/src/renderer/reepl/codemirror.cljs b/src/renderer/reepl/codemirror.cljs index 38e25c2f..515fcb28 100644 --- a/src/renderer/reepl/codemirror.cljs +++ b/src/renderer/reepl/codemirror.cljs @@ -8,6 +8,7 @@ ["codemirror/addon/runmode/runmode.js"] ["codemirror/mode/clojure/clojure.js"] ["codemirror/mode/javascript/javascript.js"] + ["codemirror/mode/python/python.js"] ["react" :as react] [clojure.string :as str] [reagent.core :as r])) diff --git a/src/renderer/reepl/core.cljs b/src/renderer/reepl/core.cljs index e5a7b54c..b2f1ca04 100644 --- a/src/renderer/reepl/core.cljs +++ b/src/renderer/reepl/core.cljs @@ -3,6 +3,7 @@ ["react-resizable-panels" :refer [Panel PanelResizeHandle]] [cljs.reader] [cljs.tools.reader] + [platform] [re-frame.core :as rf] [reagent.core :as ra] [renderer.components :as comp] @@ -91,7 +92,8 @@ cm-opts)] [:div.self-start.h-full.flex.items-center (repl-mode-button :cljs) - (repl-mode-button :js)] + (repl-mode-button :js) + (when platform/electron? (repl-mode-button :py))] [comp/toggle-icon-button {:active? repl-history? :active-icon "chevron-down" diff --git a/src/renderer/reepl/replumb.cljs b/src/renderer/reepl/replumb.cljs index 777b9e33..216ce4fa 100644 --- a/src/renderer/reepl/replumb.cljs +++ b/src/renderer/reepl/replumb.cljs @@ -237,10 +237,10 @@ cljs.js/*load-fn* (js-attrs proto)))))) (defn js-completion - [text] + [mode text] (let [parts (vec (.split text ".")) completing (or (last parts) "") - prefix #(str "js/" (str/join "." (conj (vec (butlast parts)) %))) + prefix #(str (when (= mode :cljs) "js/") (str/join "." (conj (vec (butlast parts)) %))) possibles (js-attrs (reduce aget js/window (butlast parts)))] (->> possibles (filter #(not= -1 (.indexOf % completing))) @@ -289,10 +289,13 @@ cljs.js/*load-fn* (filter matches? names)))))) (defn process-apropos - [text] - (if (zero? (.indexOf text "js/")) - (js-completion (.slice text 3)) - (cljs-completion text))) + [mode text] + (case mode + :js (js-completion mode text) + :cljs (if (zero? (.indexOf text "js/")) + (js-completion mode (.slice text 3)) + (cljs-completion text)) + :py [])) (defn get-forms [m] diff --git a/src/renderer/reepl/views.cljs b/src/renderer/reepl/views.cljs index 3e543dc2..b248498f 100644 --- a/src/renderer/reepl/views.cljs +++ b/src/renderer/reepl/views.cljs @@ -21,13 +21,20 @@ (defn root [] [reepl/repl - :execute #(replumb/run-repl (if (= @(rf/subscribe [:repl-mode]) :cljs) %1 (str "(js/eval \"" %1 "\")")) {:warning-as-error true} %2) - :complete-word replumb/process-apropos - :get-docs replumb/process-doc + :execute #(replumb/run-repl (case @(rf/subscribe [:repl-mode]) + :cljs %1 + :js (str "(js/eval \"" %1 "\")") + :py (str "(js/window.api.runPython \"" %1 "\")")) + {:warning-as-error true} %2) + :complete-word (fn [text] (replumb/process-apropos @(rf/subscribe [:repl-mode]) text)) + :get-docs (if (= @(rf/subscribe [:repl-mode]) :cljs) replumb/process-doc #()) :state repl-state :show-value-opts {:showers [show-devtools/show-devtools (partial show-function/show-fn-with-docs maybe-fn-docs)]} - :js-cm-opts {:mode (if (= @(rf/subscribe [:repl-mode]) :cljs) "clojure" "javascript") + :js-cm-opts {:mode (case + :cljs "clojure" + :js "javascript" + :py "python") :keyMap "default" :showCursorWhenSelecting true}]) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy