mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
Compare commits
13 Commits
2025.10.1
...
antocuni/p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84feb83e10 | ||
|
|
8c64d42189 | ||
|
|
e1bf5100ef | ||
|
|
b60327f022 | ||
|
|
e2d27d2cd3 | ||
|
|
90b3825369 | ||
|
|
eaf4da7c21 | ||
|
|
1867b8b89f | ||
|
|
89c212475f | ||
|
|
70e96110b0 | ||
|
|
778d37ef6c | ||
|
|
e333813fa1 | ||
|
|
6408ffa803 |
88
pyscript.core/src/plugins/py-terminal.js
Normal file
88
pyscript.core/src/plugins/py-terminal.js
Normal 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()
|
||||||
|
`);
|
||||||
23
pyscript.core/src/stdlib/pyscript/pyterminal.py
Normal file
23
pyscript.core/src/stdlib/pyscript/pyterminal.py
Normal 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
|
||||||
32
pyscript.core/test/pyterminal.html
Normal file
32
pyscript.core/test/pyterminal.html
Normal 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>
|
||||||
7
pyscript.core/types/plugins.d.ts
vendored
7
pyscript.core/types/plugins.d.ts
vendored
@@ -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;
|
||||||
|
|||||||
1
pyscript.core/types/plugins/py-terminal.d.ts
vendored
Normal file
1
pyscript.core/types/plugins/py-terminal.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export {};
|
||||||
1
pyscript.core/types/stdlib/pyscript.d.ts
vendored
1
pyscript.core/types/stdlib/pyscript.d.ts
vendored
@@ -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: {
|
||||||
|
|||||||
Reference in New Issue
Block a user