Spaces:
Running
Running
Commit ·
7509812
1
Parent(s): 22a357d
commit initial 09-12-2025 37
Browse files- src/App.js +25 -19
src/App.js
CHANGED
|
@@ -329,62 +329,67 @@ const [interactivePromptShown, setInteractivePromptShown] = useState(false);
|
|
| 329 |
// Initial Run: do NOT run if code needs interactive input and there's no accumulated stdin.
|
| 330 |
// Replace your existing handleRun with this version.
|
| 331 |
// This version clears accumulated stdin at the start so "Run" asks fresh input every time.
|
|
|
|
| 332 |
const handleRun = async () => {
|
| 333 |
const node = getNodeByPath(tree, activePath);
|
| 334 |
if (!node || node.type !== "file") {
|
| 335 |
setOutput("Select a file to run.");
|
| 336 |
return;
|
| 337 |
}
|
| 338 |
-
|
|
|
|
|
|
|
|
|
|
| 339 |
if (!selectedLang || !RUNNABLE_LANGS.includes(selectedLang)) {
|
| 340 |
setOutput(`⚠️ Run not supported for this file type.`);
|
| 341 |
return;
|
| 342 |
}
|
| 343 |
|
| 344 |
-
//
|
| 345 |
-
// (If you want the old interactive continuation behavior, remove this line.)
|
| 346 |
setAccumStdin("");
|
|
|
|
|
|
|
|
|
|
| 347 |
|
|
|
|
| 348 |
const needs = codeNeedsInput(node.content, selectedLang);
|
| 349 |
-
const haveAccum = !!(accumStdin && accumStdin.length > 0);
|
| 350 |
-
const haveLegacyStdin = !!(stdin && stdin.length > 0);
|
| 351 |
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
|
| 355 |
setAwaitingInput(true);
|
| 356 |
setInteractivePromptShown(true);
|
| 357 |
focusXtermHelper();
|
| 358 |
-
return; //
|
| 359 |
}
|
| 360 |
|
| 361 |
-
//
|
| 362 |
-
const stdinToSend =
|
| 363 |
|
| 364 |
-
|
| 365 |
-
setOutput(`[Running with stdin length=${stdinToSend ? stdinToSend.length : 0}]\n`);
|
| 366 |
setIsRunning(true);
|
| 367 |
setProblems([]);
|
| 368 |
try {
|
| 369 |
const res = await runCode(node.content, selectedLang, stdinToSend);
|
| 370 |
const out = res.output ?? "";
|
| 371 |
setOutput(out);
|
|
|
|
| 372 |
setProblems(res.error ? parseProblems(res.output) : []);
|
| 373 |
|
|
|
|
| 374 |
if (outputLooksForInput(out)) {
|
| 375 |
-
// program still waits for more input — keep accumStdin so user can continue
|
| 376 |
setAwaitingInput(true);
|
| 377 |
focusXtermHelper();
|
| 378 |
-
setInteractivePromptShown(false); // prompt already consumed / handled
|
| 379 |
} else {
|
| 380 |
-
// program finished — clear accumulated stdin so next Run asks for fresh input
|
| 381 |
setAwaitingInput(false);
|
| 382 |
setInteractivePromptShown(false);
|
| 383 |
-
setAccumStdin("");
|
| 384 |
}
|
| 385 |
} catch (err) {
|
| 386 |
-
|
| 387 |
-
|
|
|
|
|
|
|
| 388 |
setAwaitingInput(true);
|
| 389 |
setInteractivePromptShown(true);
|
| 390 |
focusXtermHelper();
|
|
@@ -395,6 +400,7 @@ const handleRun = async () => {
|
|
| 395 |
|
| 396 |
|
| 397 |
|
|
|
|
| 398 |
// Send from the small input box: delegate to runCodeWithUpdatedInput to keep behavior uniform
|
| 399 |
const sendTerminalInput = async () => {
|
| 400 |
const line = (terminalInput || "").replace(/\r$/, "");
|
|
|
|
| 329 |
// Initial Run: do NOT run if code needs interactive input and there's no accumulated stdin.
|
| 330 |
// Replace your existing handleRun with this version.
|
| 331 |
// This version clears accumulated stdin at the start so "Run" asks fresh input every time.
|
| 332 |
+
// Replace your existing handleRun with this
|
| 333 |
const handleRun = async () => {
|
| 334 |
const node = getNodeByPath(tree, activePath);
|
| 335 |
if (!node || node.type !== "file") {
|
| 336 |
setOutput("Select a file to run.");
|
| 337 |
return;
|
| 338 |
}
|
| 339 |
+
|
| 340 |
+
const selectedLang = LANGUAGE_OPTIONS.find((l) =>
|
| 341 |
+
node.name.endsWith(l.ext)
|
| 342 |
+
)?.id;
|
| 343 |
if (!selectedLang || !RUNNABLE_LANGS.includes(selectedLang)) {
|
| 344 |
setOutput(`⚠️ Run not supported for this file type.`);
|
| 345 |
return;
|
| 346 |
}
|
| 347 |
|
| 348 |
+
// --- FORCE a fresh run: clear any previous accumulated stdin and terminal ---
|
|
|
|
| 349 |
setAccumStdin("");
|
| 350 |
+
resetTerminal(false); // clear terminalLines + terminalInput and also clears accumStdin because keepAccum=false
|
| 351 |
+
setAwaitingInput(false);
|
| 352 |
+
setInteractivePromptShown(false);
|
| 353 |
|
| 354 |
+
// detect whether the code likely needs interactive input
|
| 355 |
const needs = codeNeedsInput(node.content, selectedLang);
|
|
|
|
|
|
|
| 356 |
|
| 357 |
+
// If code needs input, show a clear interactive message (do NOT run yet)
|
| 358 |
+
if (needs) {
|
| 359 |
+
appendTerminal("[Interactive program detected — type input directly into the terminal]");
|
| 360 |
setAwaitingInput(true);
|
| 361 |
setInteractivePromptShown(true);
|
| 362 |
focusXtermHelper();
|
| 363 |
+
return; // wait for user's first input (avoids EOFError)
|
| 364 |
}
|
| 365 |
|
| 366 |
+
// If not interactive, run immediately with empty stdin
|
| 367 |
+
const stdinToSend = ""; // fresh run uses no previous input
|
| 368 |
|
| 369 |
+
appendTerminal(`[Running (fresh) with stdin length=${stdinToSend.length}]`);
|
|
|
|
| 370 |
setIsRunning(true);
|
| 371 |
setProblems([]);
|
| 372 |
try {
|
| 373 |
const res = await runCode(node.content, selectedLang, stdinToSend);
|
| 374 |
const out = res.output ?? "";
|
| 375 |
setOutput(out);
|
| 376 |
+
appendTerminal(out);
|
| 377 |
setProblems(res.error ? parseProblems(res.output) : []);
|
| 378 |
|
| 379 |
+
// If output suggests further input, enter interactive mode (rare since we checked 'needs', but handle anyway)
|
| 380 |
if (outputLooksForInput(out)) {
|
|
|
|
| 381 |
setAwaitingInput(true);
|
| 382 |
focusXtermHelper();
|
|
|
|
| 383 |
} else {
|
|
|
|
| 384 |
setAwaitingInput(false);
|
| 385 |
setInteractivePromptShown(false);
|
| 386 |
+
setAccumStdin(""); // ensure accum cleared after finish
|
| 387 |
}
|
| 388 |
} catch (err) {
|
| 389 |
+
const errStr = String(err);
|
| 390 |
+
setOutput(errStr);
|
| 391 |
+
appendTerminal(errStr);
|
| 392 |
+
// if error looks like EOF or program expects input, enable interactive mode
|
| 393 |
setAwaitingInput(true);
|
| 394 |
setInteractivePromptShown(true);
|
| 395 |
focusXtermHelper();
|
|
|
|
| 400 |
|
| 401 |
|
| 402 |
|
| 403 |
+
|
| 404 |
// Send from the small input box: delegate to runCodeWithUpdatedInput to keep behavior uniform
|
| 405 |
const sendTerminalInput = async () => {
|
| 406 |
const line = (terminalInput || "").replace(/\r$/, "");
|