Compare commits

...

13 Commits

Author SHA1 Message Date
pre-commit-ci[bot]
84feb83e10 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2023-10-10 14:57:19 +00:00
Antonio Cuni
8c64d42189 missing file 2023-10-10 16:57:02 +02:00
Antonio Cuni
e1bf5100ef use lazy imports and import xterm.js only if a py-terminal is actually found 2023-10-05 16:44:42 +02:00
Antonio Cuni
b60327f022 we can kill this ugly hack now 2023-10-05 15:38:12 +02:00
Antonio Cuni
e2d27d2cd3 Merge remote-tracking branch 'origin/main' into antocuni/py-terminal 2023-10-05 15:14:54 +02:00
Antonio Cuni
90b3825369 undo this change 2023-10-05 15:14:40 +02:00
Antonio Cuni
eaf4da7c21 hack hack hack until pyterminal works also in workers 2023-09-29 19:09:20 +02:00
Antonio Cuni
1867b8b89f Merge remote-tracking branch 'origin/main' into antocuni/py-terminal 2023-09-29 16:57:24 +02:00
Antonio Cuni
89c212475f WIP: I don't understand why onWorkerReady is not called 2023-09-29 15:04:10 +02:00
Antonio Cuni
70e96110b0 rename 2023-09-29 14:42:18 +02:00
Antonio Cuni
778d37ef6c use a better approach for pyodide 2023-09-29 14:42:18 +02:00
Antonio Cuni
e333813fa1 improve the comments 2023-09-29 14:42:18 +02:00
Antonio Cuni
6408ffa803 a very hacky and very very tentative implementation sketchy implementation of the py-terminal plugin 2023-09-29 14:42:18 +02:00
6 changed files with 149 additions and 3 deletions

View File

@@ -0,0 +1,88 @@
// PyScript py-terminal plugin
import { hooks } from "../core.js";
const makePyTerminal = async () => {
const element = document.querySelector("py-terminal");
if (element === null) {
// no py-terminal found, nothing to do
return false;
}
document
.getElementsByTagName("head")[0]
.insertAdjacentHTML(
"beforeend",
'<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/xterm@5.3.0/css/xterm.min.css">',
);
const { Terminal } = await import(
/* webpackIgnore: true */ "https://cdn.jsdelivr.net/npm/xterm@5.3.0/+esm"
);
const { Readline } = await import(
/* webpackIgnore: true */ "https://cdn.jsdelivr.net/npm/xterm-readline@1.1.1/+esm"
);
const term = new Terminal({
theme: {
background: "#191A19",
foreground: "#F5F2E7",
},
cursorBlink: true,
cursorStyle: "block",
rows: 50,
});
const rl = new Readline();
term.loadAddon(rl);
term.open(element);
term.focus();
async function pyterminal_readline(prompt) {
const line = await rl.read(prompt);
return line;
}
async function pyterminal_write(line) {
rl.write(line);
}
console.log("PyTerminal made?");
return { term, pyterminal_readline, pyterminal_write };
};
// this is ONLY for non-workers, correct?
// TODO: how to make it working for workers?
hooks.onInterpreterReady.add(async function override(pyScript) {
console.log("hello onInterpreterReady");
const t = await makePyTerminal();
if (!t) {
console.log("<py-terminal> not found, nothing to do");
return;
}
// XXX: we should investigate pyodide "write handler", it should be more
// efficient:
// https://pyodide.org/en/stable/usage/streams.html#a-write-handler
//
// Also: should the stdout/stderr go ALSO to the JS console?
function myStdout(byte) {
t.write(String.fromCharCode(byte));
}
const pyodide = pyScript.interpreter;
pyodide.setStdout({ raw: myStdout });
pyodide.setStderr({ raw: myStdout });
});
hooks.onWorkerReady.add(async function (_, xworker) {
console.log("hello onWorkerReady");
const t = await makePyTerminal();
if (!t) {
console.log("<py-terminal> not found, nothing to do");
return;
}
xworker.sync.pyterminal_readline = t.pyterminal_readline;
xworker.sync.pyterminal_write = t.pyterminal_write;
});
hooks.codeBeforeRunWorker.add(`
from pyscript import pyterminal
pyterminal.init()
`);

View File

@@ -0,0 +1,23 @@
import builtins
import sys
import js
from pyscript import sync
class PyTerminal:
def write(self, line):
sync.pyterminal_write(line)
def input(self, prompt):
return sync.pyterminal_readline(prompt)
PY_TERMINAL = None
def init():
global PY_TERMINAL
PY_TERMINAL = PyTerminal()
sys.stdout = sys.stderr = PY_TERMINAL
builtins.input = PY_TERMINAL.input

View File

@@ -0,0 +1,32 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PyScript Next</title>
<script>
addEventListener("py:ready", console.log);
</script>
<link rel="stylesheet" href="../dist/core.css">
<script type="module" src="../dist/core.js"></script>
</head>
<body>
<script type="py" worker>
import sys
from pyscript import display
display("Hello", "PyScript Next", append=False)
print("this should go to the terminal")
print("another line")
# XXX we have a problem with the error plugin: this line should
# just go to the terminal, NOT to the red box in the DOM
print("this goes to stderr", file=sys.stderr)
import code
code.interact()
</script>
<py-terminal></py-terminal>
</body>
</html>

View File

@@ -1,4 +1,5 @@
declare namespace _default { declare const _default: {
function error(): Promise<typeof import("./plugins/error.js")>; error: () => Promise<typeof import("./plugins/error.js")>;
} "py-terminal": () => Promise<typeof import("./plugins/py-terminal.js")>;
};
export default _default; export default _default;

View File

@@ -0,0 +1 @@
export {};

View File

@@ -4,6 +4,7 @@ declare namespace _default {
"display.py": string; "display.py": string;
"event_handling.py": string; "event_handling.py": string;
"magic_js.py": string; "magic_js.py": string;
"pyterminal.py": string;
"util.py": string; "util.py": string;
}; };
let pyweb: { let pyweb: {