Skip to content

Commit 1b968e9

Browse files
Merge pull request #1022 from RustPython/coolreader18/demo-repl-continuation
Add line continuation for the WASM demo terminal
2 parents d45c632 + cd61248 commit 1b968e9

File tree

1 file changed

+60
-24
lines changed

1 file changed

+60
-24
lines changed

wasm/demo/src/main.js

Lines changed: 60 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,6 @@ snippets.addEventListener('change', updateSnippet);
8282
// option selected for the `select`, but the textarea won't be updated)
8383
updateSnippet();
8484

85-
const prompt = '>>>>> ';
86-
87-
const term = new Terminal();
88-
term.open(document.getElementById('terminal'));
89-
term.write(prompt);
90-
9185
function removeNonAscii(str) {
9286
if (str === null || str === '') return false;
9387
else str = str.toString();
@@ -99,38 +93,80 @@ function printToConsole(data) {
9993
term.write(removeNonAscii(data) + '\r\n');
10094
}
10195

96+
const term = new Terminal();
97+
term.open(document.getElementById('terminal'));
98+
10299
const terminalVM = rp.vmStore.init('term_vm');
103100
terminalVM.setStdout(printToConsole);
104101

105-
var input = '';
102+
function getPrompt(name = 'ps1') {
103+
terminalVM.exec(`
104+
try:
105+
import sys as __sys
106+
__prompt = __sys.${name}
107+
except:
108+
__prompt = ''
109+
finally:
110+
del __sys
111+
`);
112+
return String(terminalVM.eval('__prompt'));
113+
}
114+
115+
term.write(getPrompt());
116+
117+
function resetInput() {
118+
continuedInput = [];
119+
input = '';
120+
continuing = false;
121+
}
122+
123+
let continuedInput, input, continuing;
124+
resetInput();
125+
126+
let ps2;
127+
106128
term.on('data', data => {
107129
const code = data.charCodeAt(0);
108130
if (code == 13) {
109131
// CR
110-
if (input[input.length - 1] == ':') {
111-
input += data;
112-
term.write('\r\n.....');
113-
} else {
114-
term.write('\r\n');
115-
try {
116-
terminalVM.execSingle(input);
117-
} catch (err) {
118-
if (err instanceof WebAssembly.RuntimeError) {
119-
err = window.__RUSTPYTHON_ERROR || err;
120-
}
121-
printToConsole(err);
132+
term.write('\r\n');
133+
continuedInput.push(input);
134+
if (continuing) {
135+
if (input === '') {
136+
continuing = false;
137+
} else {
138+
input = '';
139+
term.write(ps2);
140+
return;
141+
}
142+
}
143+
try {
144+
terminalVM.execSingle(continuedInput.join('\n'));
145+
} catch (err) {
146+
if (err instanceof SyntaxError && err.message.includes('EOF')) {
147+
ps2 = getPrompt('ps2');
148+
term.write(ps2);
149+
continuing = true;
150+
input = '';
151+
return;
152+
} else if (err instanceof WebAssembly.RuntimeError) {
153+
err = window.__RUSTPYTHON_ERROR || err;
122154
}
123-
term.write(prompt);
124-
input = '';
155+
printToConsole(err);
125156
}
126-
} else if (code == 127) {
157+
resetInput();
158+
term.write(getPrompt());
159+
} else if (code == 127 || code == 8) {
160+
// Backspace
127161
if (input.length > 0) {
128162
term.write('\b \b');
129163
input = input.slice(0, -1);
130164
}
131-
} else if (code < 32 || code == 127) {
165+
} else if (code < 32) {
132166
// Control
133-
return;
167+
term.write('\r\n' + getPrompt());
168+
input = '';
169+
continuedInput = [];
134170
} else {
135171
// Visible
136172
term.write(data);

0 commit comments

Comments
 (0)