@@ -3,6 +3,7 @@ import CodeMirror from 'codemirror';
33import 'codemirror/mode/python/python' ;
44import 'codemirror/addon/comment/comment' ;
55import { Terminal } from 'xterm' ;
6+ import LocalEchoController from 'local-echo' ;
67
78// so people can play around with it
89window . rp = rp ;
@@ -35,7 +36,7 @@ function runCodeFromTextarea() {
3536
3637 const code = editor . getValue ( ) ;
3738 try {
38- const result = rp . pyEval ( code , {
39+ rp . pyEval ( code , {
3940 stdout : output => {
4041 const shouldScroll =
4142 consoleElement . scrollHeight - consoleElement . scrollTop ===
@@ -46,9 +47,6 @@ function runCodeFromTextarea() {
4647 }
4748 }
4849 } ) ;
49- if ( result !== null ) {
50- consoleElement . value += `\n${ result } \n` ;
51- }
5250 } catch ( err ) {
5351 if ( err instanceof WebAssembly . RuntimeError ) {
5452 err = window . __RUSTPYTHON_ERROR || err ;
@@ -82,24 +80,16 @@ snippets.addEventListener('change', updateSnippet);
8280// option selected for the `select`, but the textarea won't be updated)
8381updateSnippet ( ) ;
8482
85- function removeNonAscii ( str ) {
86- if ( str === null || str === '' ) return false ;
87- else str = str . toString ( ) ;
88-
89- return str . replace ( / [ ^ \x20 - \x7E ] / g, '' ) ;
90- }
91-
92- function printToConsole ( data ) {
93- term . write ( removeNonAscii ( data ) + '\r\n' ) ;
94- }
95-
9683const term = new Terminal ( ) ;
9784term . open ( document . getElementById ( 'terminal' ) ) ;
9885
86+ const localEcho = new LocalEchoController ( term ) ;
87+
9988const terminalVM = rp . vmStore . init ( 'term_vm' ) ;
100- terminalVM . setStdout ( printToConsole ) ;
10189
102- function getPrompt ( name = 'ps1' ) {
90+ terminalVM . setStdout ( data => localEcho . println ( data ) ) ;
91+
92+ function getPrompt ( name ) {
10393 terminalVM . exec ( `
10494try:
10595 import sys as __sys
@@ -112,64 +102,37 @@ finally:
112102 return String ( terminalVM . eval ( '__prompt' ) ) ;
113103}
114104
115- term . write ( getPrompt ( ) ) ;
105+ async function readPrompts ( ) {
106+ let continuing = false ;
116107
117- function resetInput ( ) {
118- continuedInput = [ ] ;
119- input = '' ;
120- continuing = false ;
121- }
122-
123- let continuedInput , input , continuing ;
124- resetInput ( ) ;
125-
126- let ps2 ;
127-
128- term . on ( 'data' , data => {
129- const code = data . charCodeAt ( 0 ) ;
130- if ( code == 13 ) {
131- // CR
132- term . write ( '\r\n' ) ;
133- continuedInput . push ( input ) ;
108+ while ( true ) {
109+ const ps1 = getPrompt ( 'ps1' ) ;
110+ const ps2 = getPrompt ( 'ps2' ) ;
111+ let input ;
134112 if ( continuing ) {
135- if ( input === '' ) {
136- continuing = false ;
137- } else {
138- input = '' ;
139- term . write ( ps2 ) ;
140- return ;
141- }
113+ const prom = localEcho . read ( ps2 , ps2 ) ;
114+ localEcho . _activePrompt . prompt = ps1 ;
115+ localEcho . _input = localEcho . history . entries . pop ( ) + '\n' ;
116+ localEcho . _cursor = localEcho . _input . length ;
117+ localEcho . _active = true ;
118+ input = await prom ;
119+ if ( ! input . endsWith ( '\n' ) ) continue ;
120+ } else {
121+ input = await localEcho . read ( ps1 , ps2 ) ;
142122 }
143123 try {
144- terminalVM . execSingle ( continuedInput . join ( '\n' ) ) ;
124+ terminalVM . execSingle ( input ) ;
145125 } catch ( err ) {
146126 if ( err instanceof SyntaxError && err . message . includes ( 'EOF' ) ) {
147- ps2 = getPrompt ( 'ps2' ) ;
148- term . write ( ps2 ) ;
149127 continuing = true ;
150- input = '' ;
151- return ;
128+ continue ;
152129 } else if ( err instanceof WebAssembly . RuntimeError ) {
153130 err = window . __RUSTPYTHON_ERROR || err ;
154131 }
155- printToConsole ( err ) ;
132+ localEcho . println ( err ) ;
156133 }
157- resetInput ( ) ;
158- term . write ( getPrompt ( ) ) ;
159- } else if ( code == 127 || code == 8 ) {
160- // Backspace
161- if ( input . length > 0 ) {
162- term . write ( '\b \b' ) ;
163- input = input . slice ( 0 , - 1 ) ;
164- }
165- } else if ( code < 32 ) {
166- // Control
167- term . write ( '\r\n' + getPrompt ( ) ) ;
168- input = '' ;
169- continuedInput = [ ] ;
170- } else {
171- // Visible
172- term . write ( data ) ;
173- input += data ;
134+ continuing = false ;
174135 }
175- } ) ;
136+ }
137+
138+ readPrompts ( ) . catch ( err => console . error ( err ) ) ;
0 commit comments