Spaces:
Running
Running
Commit ·
1700d78
1
Parent(s): a405934
commit initial 09-12-2025 022
Browse files- src/App.js +55 -8
src/App.js
CHANGED
|
@@ -242,7 +242,58 @@ function codeNeedsInput(code, langId) {
|
|
| 242 |
return false;
|
| 243 |
}
|
| 244 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
const handleRun = async () => {
|
| 247 |
const node = getNodeByPath(tree, activePath);
|
| 248 |
if (!node || node.type !== "file") {
|
|
@@ -536,16 +587,12 @@ function codeNeedsInput(code, langId) {
|
|
| 536 |
{/* Bottom panels */}
|
| 537 |
<div className="ide-panels">
|
| 538 |
{/* Terminal output */}
|
| 539 |
-
|
| 540 |
output={output}
|
| 541 |
onData={(userInputLine) => {
|
| 542 |
-
//
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
// If waiting for next input, resume execution or re-run code
|
| 546 |
-
if (awaitingInput) {
|
| 547 |
-
runCodeWithUpdatedInput();
|
| 548 |
-
}
|
| 549 |
}}
|
| 550 |
/>
|
| 551 |
|
|
|
|
| 242 |
return false;
|
| 243 |
}
|
| 244 |
}
|
| 245 |
+
// ----------------------
|
| 246 |
+
// Call this whenever a new terminal line arrives (from xterm onData)
|
| 247 |
+
// It appends the line to accumulated stdin and re-runs the current file.
|
| 248 |
+
// Uses a local variable for stdin to avoid setState races.
|
| 249 |
+
// ----------------------
|
| 250 |
+
const runCodeWithUpdatedInput = async (inputLine) => {
|
| 251 |
+
// echo the line in terminal UI
|
| 252 |
+
appendTerminal(`> ${inputLine}`);
|
| 253 |
+
|
| 254 |
+
// build new accumulated stdin locally (so we can use it immediately)
|
| 255 |
+
const newAccum = (accumStdin || "") + inputLine + "\n";
|
| 256 |
+
// update state so further interactions know about it
|
| 257 |
+
setAccumStdin(newAccum);
|
| 258 |
|
| 259 |
+
// get current file node
|
| 260 |
+
const node = getNodeByPath(tree, activePath);
|
| 261 |
+
if (!node || node.type !== "file") {
|
| 262 |
+
appendTerminal("[Error] No file selected to run.");
|
| 263 |
+
setAwaitingInput(false);
|
| 264 |
+
return;
|
| 265 |
+
}
|
| 266 |
+
|
| 267 |
+
const selectedLang = LANGUAGE_OPTIONS.find((l) => node.name.endsWith(l.ext))?.id;
|
| 268 |
+
if (!selectedLang || !RUNNABLE_LANGS.includes(selectedLang)) {
|
| 269 |
+
appendTerminal(`[Error] Run not supported for ${node.name}`);
|
| 270 |
+
setAwaitingInput(false);
|
| 271 |
+
return;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
// run immediately with local stdin (newAccum)
|
| 275 |
+
setIsRunning(true);
|
| 276 |
+
try {
|
| 277 |
+
const res = await runCode(node.content, selectedLang, newAccum);
|
| 278 |
+
const out = res.output ?? "";
|
| 279 |
+
setOutput(out);
|
| 280 |
+
appendTerminal(out);
|
| 281 |
+
setProblems(res.error ? parseProblems(res.output) : []);
|
| 282 |
+
|
| 283 |
+
// if output indicates program needs more input, keep awaitingInput true
|
| 284 |
+
if (outputLooksForInput(out)) {
|
| 285 |
+
setAwaitingInput(true);
|
| 286 |
+
} else {
|
| 287 |
+
setAwaitingInput(false);
|
| 288 |
+
}
|
| 289 |
+
} catch (err) {
|
| 290 |
+
const errText = String(err);
|
| 291 |
+
appendTerminal(errText);
|
| 292 |
+
setAwaitingInput(false);
|
| 293 |
+
} finally {
|
| 294 |
+
setIsRunning(false);
|
| 295 |
+
}
|
| 296 |
+
};
|
| 297 |
const handleRun = async () => {
|
| 298 |
const node = getNodeByPath(tree, activePath);
|
| 299 |
if (!node || node.type !== "file") {
|
|
|
|
| 587 |
{/* Bottom panels */}
|
| 588 |
<div className="ide-panels">
|
| 589 |
{/* Terminal output */}
|
| 590 |
+
<XTerm
|
| 591 |
output={output}
|
| 592 |
onData={(userInputLine) => {
|
| 593 |
+
// previously you called setAccumStdin(...) or undefined runCodeWithUpdatedInput
|
| 594 |
+
// Now call the defined function:
|
| 595 |
+
runCodeWithUpdatedInput(userInputLine);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 596 |
}}
|
| 597 |
/>
|
| 598 |
|