Improve the terminal's navigation

This commit is contained in:
coolreader18
2019-09-29 12:54:40 -05:00
parent af10174cf8
commit 2160f68d09
2 changed files with 34 additions and 70 deletions

View File

@@ -5,6 +5,7 @@
"main": "index.js",
"dependencies": {
"codemirror": "^5.42.0",
"local-echo": "^0.2.0",
"xterm": "^3.8.0"
},
"devDependencies": {
@@ -14,11 +15,11 @@
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.5.0",
"raw-loader": "^1.0.0",
"serve": "^11.0.2",
"start-server-and-test": "^1.7.11",
"webpack": "^4.16.3",
"webpack-cli": "^3.1.0",
"webpack-dev-server": "^3.1.5",
"start-server-and-test": "^1.7.11",
"serve": "^11.0.2"
"webpack-dev-server": "^3.1.5"
},
"scripts": {
"dev": "webpack-dev-server -d",

View File

@@ -3,6 +3,7 @@ import CodeMirror from 'codemirror';
import 'codemirror/mode/python/python';
import 'codemirror/addon/comment/comment';
import { Terminal } from 'xterm';
import LocalEchoController from 'local-echo';
// so people can play around with it
window.rp = rp;
@@ -35,7 +36,7 @@ function runCodeFromTextarea() {
const code = editor.getValue();
try {
const result = rp.pyEval(code, {
rp.pyEval(code, {
stdout: output => {
const shouldScroll =
consoleElement.scrollHeight - consoleElement.scrollTop ===
@@ -46,9 +47,6 @@ function runCodeFromTextarea() {
}
}
});
if (result !== null) {
consoleElement.value += `\n${result}\n`;
}
} catch (err) {
if (err instanceof WebAssembly.RuntimeError) {
err = window.__RUSTPYTHON_ERROR || err;
@@ -82,24 +80,16 @@ snippets.addEventListener('change', updateSnippet);
// option selected for the `select`, but the textarea won't be updated)
updateSnippet();
function removeNonAscii(str) {
if (str === null || str === '') return false;
else str = str.toString();
return str.replace(/[^\x20-\x7E]/g, '');
}
function printToConsole(data) {
term.write(removeNonAscii(data) + '\r\n');
}
const term = new Terminal();
term.open(document.getElementById('terminal'));
const terminalVM = rp.vmStore.init('term_vm');
terminalVM.setStdout(printToConsole);
const localEcho = new LocalEchoController(term);
function getPrompt(name = 'ps1') {
const terminalVM = rp.vmStore.init('term_vm');
terminalVM.setStdout(data => localEcho.println(data));
function getPrompt(name) {
terminalVM.exec(`
try:
import sys as __sys
@@ -112,64 +102,37 @@ finally:
return String(terminalVM.eval('__prompt'));
}
term.write(getPrompt());
async function readPrompts() {
let continuing = false;
function resetInput() {
continuedInput = [];
input = '';
continuing = false;
}
let continuedInput, input, continuing;
resetInput();
let ps2;
term.on('data', data => {
const code = data.charCodeAt(0);
if (code == 13) {
// CR
term.write('\r\n');
continuedInput.push(input);
while (true) {
const ps1 = getPrompt('ps1');
const ps2 = getPrompt('ps2');
let input;
if (continuing) {
if (input === '') {
continuing = false;
} else {
input = '';
term.write(ps2);
return;
}
const prom = localEcho.read(ps2, ps2);
localEcho._activePrompt.prompt = ps1;
localEcho._input = localEcho.history.entries.pop() + '\n';
localEcho._cursor = localEcho._input.length;
localEcho._active = true;
input = await prom;
if (!input.endsWith('\n')) continue;
} else {
input = await localEcho.read(ps1, ps2);
}
try {
terminalVM.execSingle(continuedInput.join('\n'));
terminalVM.execSingle(input);
} catch (err) {
if (err instanceof SyntaxError && err.message.includes('EOF')) {
ps2 = getPrompt('ps2');
term.write(ps2);
continuing = true;
input = '';
return;
continue;
} else if (err instanceof WebAssembly.RuntimeError) {
err = window.__RUSTPYTHON_ERROR || err;
}
printToConsole(err);
localEcho.println(err);
}
resetInput();
term.write(getPrompt());
} else if (code == 127 || code == 8) {
// Backspace
if (input.length > 0) {
term.write('\b \b');
input = input.slice(0, -1);
}
} else if (code < 32) {
// Control
term.write('\r\n' + getPrompt());
input = '';
continuedInput = [];
} else {
// Visible
term.write(data);
input += data;
continuing = false;
}
});
}
readPrompts().catch(err => console.error(err));