@@ -17,7 +17,13 @@ import { useEmbedContext } from "./embedContext";
1717import { emptyMutex , langConstants , RuntimeLang , useRuntime } from "./runtime" ;
1818import clsx from "clsx" ;
1919
20- export type ReplOutputType = "stdout" | "stderr" | "error" | "return" | "trace" | "system" ;
20+ export type ReplOutputType =
21+ | "stdout"
22+ | "stderr"
23+ | "error"
24+ | "return"
25+ | "trace"
26+ | "system" ;
2127export interface ReplOutput {
2228 type : ReplOutputType ; // 出力の種類
2329 message : string ; // 出力メッセージ
@@ -30,47 +36,37 @@ export type SyntaxStatus = "complete" | "incomplete" | "invalid"; // 構文チ
3036
3137export function writeOutput (
3238 term : Terminal ,
33- outputs : ReplOutput [ ] ,
34- endNewLine : boolean ,
39+ output : ReplOutput ,
3540 returnPrefix : string | undefined ,
3641 Prism : typeof import ( "prismjs" ) | null ,
3742 language : RuntimeLang
3843) {
39- for ( let i = 0 ; i < outputs . length ; i ++ ) {
40- const output = outputs [ i ] ;
41- if ( i > 0 ) {
42- term . writeln ( "" ) ;
43- }
44- // 出力内容に応じて色を変える
45- const message = String ( output . message ) . replace ( / \n / g, "\r\n" ) ;
46- switch ( output . type ) {
47- case "error" :
48- term . write ( chalk . red ( message ) ) ;
49- break ;
50- case "trace" :
51- term . write ( chalk . blue . italic ( message ) ) ;
52- break ;
53- case "system" :
54- term . write ( systemMessageColor ( message ) ) ;
55- break ;
56- case "return" :
57- if ( returnPrefix ) {
58- term . write ( returnPrefix ) ;
59- }
60- if ( Prism ) {
61- term . write ( highlightCodeToAnsi ( Prism , message , language ) ) ;
62- } else {
63- console . warn ( "Prism is not loaded, cannot highlight return value" ) ;
64- term . write ( message ) ;
65- }
66- break ;
67- default :
68- term . write ( message ) ;
69- break ;
70- }
71- }
72- if ( endNewLine && outputs . length > 0 ) {
73- term . writeln ( "" ) ;
44+ // 出力内容に応じて色を変える
45+ const message = String ( output . message ) . replace ( / \n / g, "\r\n" ) ;
46+ switch ( output . type ) {
47+ case "error" :
48+ term . writeln ( chalk . red ( message ) ) ;
49+ break ;
50+ case "trace" :
51+ term . writeln ( chalk . blue . italic ( message ) ) ;
52+ break ;
53+ case "system" :
54+ term . writeln ( systemMessageColor ( message ) ) ;
55+ break ;
56+ case "return" :
57+ if ( returnPrefix ) {
58+ term . write ( returnPrefix ) ;
59+ }
60+ if ( Prism ) {
61+ term . writeln ( highlightCodeToAnsi ( Prism , message , language ) ) ;
62+ } else {
63+ console . warn ( "Prism is not loaded, cannot highlight return value" ) ;
64+ term . writeln ( message ) ;
65+ }
66+ break ;
67+ default :
68+ term . writeln ( message ) ;
69+ break ;
7470 }
7571}
7672
@@ -176,21 +172,18 @@ export function ReplTerminal({
176172
177173 // ランタイムからのoutputを描画し、inputBufferをリセット
178174 const handleOutput = useCallback (
179- ( outputs : ReplOutput [ ] ) => {
175+ ( output : ReplOutput ) => {
180176 if ( terminalInstanceRef . current ) {
181177 writeOutput (
182178 terminalInstanceRef . current ,
183- outputs ,
184- true ,
179+ output ,
185180 returnPrefix ,
186181 Prism ,
187182 language
188183 ) ;
189- // 出力が終わったらプロンプトを表示
190- updateBuffer ( ( ) => [ "" ] ) ;
191184 }
192185 } ,
193- [ Prism , updateBuffer , terminalInstanceRef , returnPrefix , language ]
186+ [ Prism , terminalInstanceRef , returnPrefix , language ]
194187 ) ;
195188
196189 const keyHandler = useCallback (
@@ -220,11 +213,15 @@ export function ReplTerminal({
220213 terminalInstanceRef . current . writeln ( "" ) ;
221214 const command = inputBuffer . current . join ( "\n" ) . trim ( ) ;
222215 inputBuffer . current = [ ] ;
223- const outputs = await runtimeMutex . runExclusive ( ( ) =>
224- runCommand ( command )
225- ) ;
226- handleOutput ( outputs ) ;
227- addReplOutput ?.( terminalId , command , outputs ) ;
216+ const collectedOutputs : ReplOutput [ ] = [ ] ;
217+ await runtimeMutex . runExclusive ( async ( ) => {
218+ await runCommand ( command , ( output ) => {
219+ collectedOutputs . push ( output ) ;
220+ handleOutput ( output ) ;
221+ } ) ;
222+ } ) ;
223+ updateBuffer ( ( ) => [ "" ] ) ;
224+ addReplOutput ?.( terminalId , command , collectedOutputs ) ;
228225 }
229226 } else if ( code === 127 ) {
230227 // Backspace
@@ -301,8 +298,13 @@ export function ReplTerminal({
301298 updateBuffer ( ( ) => cmd . command . split ( "\n" ) ) ;
302299 terminalInstanceRef . current ! . writeln ( "" ) ;
303300 inputBuffer . current = [ ] ;
304- handleOutput ( cmd . output ) ;
301+ for ( const output of cmd . output ) {
302+ handleOutput ( output ) ;
303+ }
304+ updateBuffer ( ( ) => [ "" ] ) ;
305305 }
306+ } else {
307+ updateBuffer ( ( ) => [ "" ] ) ;
306308 }
307309 terminalInstanceRef . current ! . scrollToTop ( ) ;
308310 setInitCommandState ( "idle" ) ;
@@ -320,7 +322,10 @@ export function ReplTerminal({
320322 const initCommandResult : ReplCommand [ ] = [ ] ;
321323 await runtimeMutex . runExclusive ( async ( ) => {
322324 for ( const cmd of initCommand ! ) {
323- const outputs = await runCommand ( cmd . command ) ;
325+ const outputs : ReplOutput [ ] = [ ] ;
326+ await runCommand ( cmd . command , ( output ) => {
327+ outputs . push ( output ) ;
328+ } ) ;
324329 initCommandResult . push ( {
325330 command : cmd . command ,
326331 output : outputs ,
@@ -333,7 +338,10 @@ export function ReplTerminal({
333338 updateBuffer ( ( ) => cmd . command . split ( "\n" ) ) ;
334339 terminalInstanceRef . current ! . writeln ( "" ) ;
335340 inputBuffer . current = [ ] ;
336- handleOutput ( cmd . output ) ;
341+ for ( const output of cmd . output ) {
342+ handleOutput ( output ) ;
343+ }
344+ updateBuffer ( ( ) => [ "" ] ) ;
337345 }
338346 }
339347 updateBuffer ( ( ) => [ "" ] ) ;
0 commit comments