Skip to content

Commit b688663

Browse files
committed
WASM REPL: some organization, refactoring, fixes for history
1 parent 4cfa3f1 commit b688663

File tree

1 file changed

+83
-72
lines changed

1 file changed

+83
-72
lines changed

Tools/wasm/emscripten/web_example/python.html

Lines changed: 83 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@
167167

168168
this.cursorPosition = 0;
169169
this.history = [];
170+
this.historyBuffer = [];
170171
this.historyIndex = -1;
171172
this.beforeHistoryNav = "";
172173
}
@@ -219,10 +220,10 @@
219220
this.cursorLeft();
220221
break;
221222
case '[H': // home key
222-
this.cursorHome();
223+
this.cursorHome(true);
223224
break;
224225
case '[F': // end key
225-
this.cursorEnd();
226+
this.cursorEnd(true);
226227
break;
227228
case '[3~': // delete key
228229
this.deleteAtCursor();
@@ -248,7 +249,6 @@
248249
case "\x03": // CTRL+C
249250
this.input = "";
250251
this.xterm.write("\n")
251-
// this is a real hack. the hard-coded 4... :\
252252
this.xterm.write('\x1b[' + (this.cursorPosition + 4) + 'D');
253253
this.cursorPosition = 0;
254254
this.resolveInput("" + '\n');
@@ -270,9 +270,14 @@
270270
}
271271
} else {
272272
this.handleCursorInsert(data);
273+
this.updateHistory();
273274
}
274275
};
275276

277+
clearLine(){
278+
this.xterm.write('\x1b[K')
279+
}
280+
276281
writeLine(line) {
277282
this.xterm.write(line.slice(0, -1));
278283
this.xterm.write("\r\n");
@@ -288,6 +293,25 @@
288293
this.xterm.write(trailing);
289294
this.xterm.write('\x1b[' + trailing.length + 'D');
290295
}
296+
this.updateHistory();
297+
}
298+
299+
handleTab() {
300+
// handle tabs: from the current position, add spaces until
301+
// this.cursorPosition is a multiple of 4.
302+
const prefix = this.input.slice(0, this.cursorPosition);
303+
const suffix = this.input.slice(this.cursorPosition);
304+
const count = 4 - (this.cursorPosition % 4);
305+
const toAdd = " ".repeat(count);
306+
this.input = prefix + toAdd + suffix
307+
this.cursorHome(false);
308+
this.clearLine();
309+
this.xterm.write(this.input);
310+
if (suffix){
311+
this.xterm.write('\x1b[' + suffix.length + 'D');
312+
}
313+
this.cursorPosition += count;
314+
this.updateHistory(false);
291315
}
292316

293317
handleCursorErase() {
@@ -300,24 +324,63 @@
300324
}
301325
const trailing = this.input.slice(this.cursorPosition);
302326
this.input = this.input.slice(0, this.cursorPosition - 1) + trailing;
303-
this.cursorPosition -= 1;
304-
this.xterm.write("\x1B[D");
305-
this.xterm.write("\x1B[K");
306-
if (trailing){
327+
this.cursorLeft();
328+
this.clearLine();
329+
if (trailing.length !== 0){
307330
this.xterm.write(trailing);
308331
this.xterm.write('\x1b[' + trailing.length + 'D');
309332
}
333+
this.updateHistory();
310334
}
311335

312336
deleteAtCursor(){
313337
if (this.cursorPosition < this.input.length){
314338
const trailing = this.input.slice(this.cursorPosition + 1);
315339
this.input = this.input.slice(0, this.cursorPosition) + trailing;
316-
this.xterm.write("\x1B[K");
317-
if (trailing){
340+
this.clearLine();
341+
if (trailing.length !== 0){
318342
this.xterm.write(trailing);
319343
this.xterm.write('\x1b[' + trailing.length + 'D');
320344
}
345+
this.updateHistory();
346+
}
347+
}
348+
349+
cursorRight(){
350+
if (this.cursorPosition < this.input.length){
351+
this.cursorPosition += 1;
352+
this.xterm.write('\x1b[C');
353+
}
354+
}
355+
356+
cursorLeft(){
357+
if (this.cursorPosition > 0){
358+
this.cursorPosition -= 1;
359+
this.xterm.write('\x1b[D');
360+
}
361+
}
362+
363+
cursorHome(updatePosition) {
364+
if (this.cursorPosition > 0){
365+
this.xterm.write('\x1b[' + this.cursorPosition + 'D');
366+
if (updatePosition) {
367+
this.cursorPosition = 0;
368+
}
369+
}
370+
}
371+
372+
cursorEnd() {
373+
if (this.cursorPosition < this.input.length){
374+
this.xterm.write('\x1b[' + (this.input.length - this.cursorPosition) + 'C');
375+
this.cursorPosition = this.input.length;
376+
}
377+
}
378+
379+
updateHistory(){
380+
if (this.historyIndex !== -1){
381+
this.historyBuffer[this.historyIndex] = this.input;
382+
}else{
383+
this.beforeHistoryNav = this.input;
321384
}
322385
}
323386

@@ -333,13 +396,9 @@
333396
}else if (this.historyIndex > 0){
334397
this.historyIndex -= 1;
335398
}
336-
this.input = this.history[this.historyIndex];
337-
// jump back to the start of the line
338-
if (this.cursorPosition > 0){
339-
this.xterm.write('\x1b[' + (this.cursorPosition) + 'D');
340-
}
341-
// clear the line
342-
this.xterm.write('\x1b[K')
399+
this.input = this.historyBuffer[this.historyIndex];
400+
this.cursorHome(false);
401+
this.clearLine();
343402
this.xterm.write(this.input);
344403
this.cursorPosition = this.input.length;
345404
}
@@ -350,72 +409,20 @@
350409
return;
351410
}else if (this.historyIndex < this.history.length - 1){
352411
this.historyIndex += 1;
353-
this.input = this.history[this.historyIndex];
412+
this.input = this.historyBuffer[this.historyIndex];
354413
}else if (this.historyIndex == this.history.length - 1){
355414
// we're coming back from the last history value; reset
356415
// the input to whatever it was when we started going
357416
// through the history
358417
this.input = this.beforeHistoryNav;
359418
this.historyIndex = -1;
360419
}
361-
// jump back to the start of the line
362-
if (this.cursorPosition > 0){
363-
this.xterm.write('\x1b[' + (this.cursorPosition) + 'D');
364-
}
365-
// clear the line
366-
this.xterm.write('\x1b[K')
420+
this.cursorHome(false);
421+
this.clearLine();
367422
this.xterm.write(this.input);
368423
this.cursorPosition = this.input.length;
369424
}
370425

371-
cursorRight(){
372-
if (this.cursorPosition < this.input.length){
373-
this.cursorPosition += 1;
374-
this.xterm.write('\x1b[C');
375-
}
376-
}
377-
378-
cursorLeft(){
379-
if (this.cursorPosition > 0){
380-
this.cursorPosition -= 1;
381-
this.xterm.write('\x1b[D');
382-
}
383-
}
384-
385-
cursorHome() {
386-
if (this.cursorPosition > 0){
387-
this.xterm.write('\x1b[' + this.cursorPosition + 'D');
388-
this.cursorPosition = 0;
389-
}
390-
}
391-
392-
cursorEnd() {
393-
if (this.cursorPosition < this.input.length){
394-
this.xterm.write('\x1b[' + (this.input.length - this.cursorPosition) + 'C');
395-
this.cursorPosition = this.input.length;
396-
}
397-
}
398-
399-
handleTab() {
400-
// handle tabs: from the current position, add spaces until
401-
// this.cursorPosition is a multiple of 4.
402-
const prefix = this.input.slice(0, this.cursorPosition);
403-
const suffix = this.input.slice(this.cursorPosition);
404-
const count = 4 - (this.cursorPosition % 4);
405-
const toAdd = " ".repeat(count);
406-
this.input = prefix + toAdd + suffix;
407-
if (this.cursorPosition > 0){
408-
this.xterm.write('\x1b[' + (this.cursorPosition) + 'D');
409-
}
410-
// clear the line
411-
this.xterm.write('\x1b[K')
412-
this.xterm.write(this.input);
413-
if (suffix){
414-
this.xterm.write('\x1b[' + suffix.length + 'D');
415-
}
416-
this.cursorPosition += count;
417-
}
418-
419426
prompt = async () => {
420427
this.activeInput = true;
421428
// Hack to allow stdout/stderr to finish before we figure out where input starts
@@ -442,8 +449,12 @@
442449
}
443450
return new Promise((resolve, reject) => {
444451
this.resolveInput = (value) => {
445-
if (value !== ""){
452+
if (value.replace(/\s/g, '').length != 0){
453+
if (this.historyIndex !== -1){
454+
this.historyBuffer[this.historyIndex] = this.history[this.historyIndex];
455+
}
446456
this.history.push(value.slice(0, -1));
457+
this.historyBuffer.push(value.slice(0, -1));
447458
this.historyIndex = -1;
448459
this.cursorPosition = 0;
449460
}

0 commit comments

Comments
 (0)