@@ -514,6 +514,109 @@ if (repl && messageWasEmpty) {
514514 await doStreamResponse ( ) ;
515515}
516516
517+ let nextBuffer = "" ;
518+ async function readInput ( ) {
519+ let strBuffer = "" ;
520+ let arrayBuffer = new Uint8Array ( 1 ) ; // Buffer to hold byte data from stdin
521+
522+ let done = false ;
523+ let newline = false ;
524+
525+ const updateFn = async ( ) => {
526+ // read from stdin
527+ const n = await Deno . stdin . read ( arrayBuffer )
528+
529+ let curBuffer = ""
530+ const wasDone = done
531+
532+ if ( n != null && n > 0 ) {
533+ const text = new TextDecoder ( ) . decode ( arrayBuffer )
534+
535+ for ( const char of text ) {
536+ const code = char . charCodeAt ( 0 ) ;
537+ if ( code === 13 || code === 10 ) {
538+ // carriage return or newline
539+ newline = true
540+ curBuffer += "\n" ;
541+ await Deno . stdout . write ( new TextEncoder ( ) . encode ( "\n" ) ) ;
542+ }
543+ else if ( code === 127 ) {
544+ // backspace
545+ const wasEmpty = strBuffer . length === 0 ;
546+ curBuffer = curBuffer . slice ( 0 , - 1 ) ;
547+ strBuffer = strBuffer . slice ( 0 , - 1 ) ;
548+
549+ if ( ! wasEmpty ) {
550+ await Deno . stdout . write ( new TextEncoder ( ) . encode ( "\b \b" ) ) ;
551+ }
552+ }
553+ else {
554+ // any other character
555+ // console.warn("Z", char)
556+ await Deno . stdout . write ( arrayBuffer ) ;
557+ curBuffer += char ;
558+ newline = false ;
559+ }
560+ }
561+
562+ if ( wasDone ) {
563+ // We already finished reading this stream, so push to next reader
564+ nextBuffer = curBuffer
565+ }
566+ else {
567+ strBuffer += curBuffer
568+ }
569+
570+ }
571+ else {
572+ done = true ;
573+ newline = true ;
574+ return ;
575+ }
576+ } ;
577+
578+ nextBuffer = ""
579+ Deno . stdin . setRaw ( false )
580+ Deno . stdin . setRaw ( true , { cbreak : true } )
581+
582+ await new Promise ( ( resolve ) => {
583+ (
584+ async ( ) => {
585+ strBuffer = ""
586+ arrayBuffer = new Uint8Array ( 1 )
587+ while ( ! done ) {
588+ if ( nextBuffer ) {
589+ // HACK: there may be another stdin reader which we want to push results from
590+ // Use this instead of AbortController for now
591+ strBuffer = `${ nextBuffer } ${ strBuffer } `
592+ nextBuffer = ""
593+ }
594+ const wasNewline = newline ;
595+ if ( wasNewline ) {
596+ // wait for a moment for typing
597+ setTimeout ( ( ) => {
598+ if ( ! newline ) {
599+ return
600+ }
601+ done = true
602+ resolve ( true )
603+ } , 250 )
604+ }
605+ await updateFn ( ) ;
606+ if ( wasNewline && newline ) {
607+ done = true ;
608+ }
609+ }
610+ resolve ( true )
611+ }
612+ ) ( )
613+ } )
614+
615+ Deno . stdin . setRaw ( false )
616+
617+ return strBuffer
618+ }
619+
517620// Done, write it out
518621const flush = async ( ) => {
519622 streamResponse = null ;
@@ -549,7 +652,9 @@ const flush = async () => {
549652 await printCtrlSequence ( "blue" ) ;
550653 await printCtrlSequence ( "bold" ) ;
551654
552- const promptValue = prompt ( `\n>` ) ;
655+ await Deno . stdout . write ( new TextEncoder ( ) . encode ( `\n> ` ) ) ;
656+
657+ const promptValue = await readInput ( ) ;
553658
554659 // print reset ctrl sequence
555660 await printCtrlSequence ( "reset" ) ;
0 commit comments