@@ -354,6 +354,16 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
354
354
. concat ( [ Processing ( curState . blocks [ rerunIdx ] , event , event . evaluatorOptions . isExperimental , true ) ] )
355
355
. concat ( curState . blocks . slice ( rerunIdx + 1 ) ) // everything after
356
356
}
357
+ } else if ( this . hasActiveBlock ( curState ) ) {
358
+ // Transform the active block to Processing
359
+ const activeBlockIdx = this . findActiveBlock ( curState )
360
+
361
+ return {
362
+ blocks : curState . blocks
363
+ . slice ( 0 , activeBlockIdx )
364
+ . concat ( [ Processing ( curState . blocks [ activeBlockIdx ] , event , event . evaluatorOptions . isExperimental ) ] )
365
+ . concat ( curState . blocks . slice ( activeBlockIdx + 1 ) )
366
+ }
357
367
} else {
358
368
// Transform the last block to Processing
359
369
return {
@@ -406,7 +416,8 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
406
416
. slice ( 0 , inProcessIdx ) // everything before
407
417
. concat ( [ Finished ( inProcess , event , prefersTerminalPresentation , outputOnly ) ] ) // mark as finished
408
418
. concat ( curState . blocks . slice ( inProcessIdx + 1 ) ) // everything after
409
- . concat ( ! inProcess . isRerun ? [ Active ( ) ] : [ ] ) // plus a new block!
419
+ . concat ( ! inProcess . isRerun && ! this . hasActiveBlock ( curState ) ? [ Active ( ) ] : [ ] ) // plus a new block!
420
+
410
421
return {
411
422
blocks
412
423
}
@@ -418,13 +429,14 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
418
429
console . error ( 'invalid state: got a command completion event for a block that is not processing' , event )
419
430
}
420
431
} else if ( event . cancelled ) {
421
- // we get here if the user just types ctrl+c without having executed any command. add a new block!
422
- const inProcessIdx = curState . blocks . length - 1
432
+ // we get here if the user just types ctrl+c without having executed any command. add a new block if needed !
433
+ const inProcessIdx = this . hasActiveBlock ( curState ) ? this . findActiveBlock ( curState ) : curState . blocks . length - 1
423
434
const inProcess = curState . blocks [ inProcessIdx ]
424
435
const blocks = curState . blocks
425
436
. slice ( 0 , inProcessIdx )
426
437
. concat ( [ Cancelled ( inProcess ) ] ) // mark as cancelled
427
- . concat ( [ Active ( ) ] ) // plus a new block!
438
+ . concat ( curState . blocks . slice ( inProcessIdx + 1 ) )
439
+ . concat ( inProcessIdx === curState . blocks . length - 1 ? [ Active ( ) ] : [ ] ) // plus a new block if needed
428
440
return {
429
441
blocks
430
442
}
@@ -640,6 +652,18 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
640
652
} )
641
653
}
642
654
655
+ /** insert an active block before the given idx */
656
+ private willInsertBlock ( uuid : string , idx : number ) {
657
+ this . splice ( uuid , curState => {
658
+ return {
659
+ blocks : curState . blocks
660
+ . slice ( 0 , idx )
661
+ . concat ( [ Active ( ) ] )
662
+ . concat ( curState . blocks . slice ( idx ) )
663
+ }
664
+ } )
665
+ }
666
+
643
667
/** remove the block at the given index */
644
668
private willRemoveBlock ( uuid : string , idx : number ) {
645
669
this . splice ( uuid , curState => {
@@ -649,11 +673,21 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
649
673
blocks : curState . blocks
650
674
. slice ( 0 , idx )
651
675
. concat ( curState . blocks . slice ( idx + 1 ) )
652
- . concat ( curState . blocks . find ( _ => isActive ( _ ) ) ? [ ] : [ Active ( ) ] ) // plus a new block, if needed
676
+ . concat ( this . hasActiveBlock ( curState ) ? [ ] : [ Active ( ) ] ) // plus a new block, if needed
653
677
}
654
678
} )
655
679
}
656
680
681
+ /** whether the given scrollback has Active Block */
682
+ private hasActiveBlock ( scrollback : ScrollbackState ) {
683
+ return scrollback . blocks . findIndex ( b => isActive ( b ) ) > - 1
684
+ }
685
+
686
+ /** return the index of the Active Block from a scrollback */
687
+ private findActiveBlock ( scrollback : ScrollbackState ) {
688
+ return scrollback . blocks . findIndex ( b => isActive ( b ) )
689
+ }
690
+
657
691
private tabRefFor ( scrollback : ScrollbackState , ref : HTMLElement ) {
658
692
if ( ref ) {
659
693
ref [ 'facade' ] = scrollback . facade
@@ -814,17 +848,21 @@ export default class ScrollableTerminal extends React.PureComponent<Props, State
814
848
tab = { tab }
815
849
noActiveInput = { this . props . noActiveInput }
816
850
onOutputRender = { this . onOutputRender . bind ( this , scrollback ) }
851
+ willInsertBlock = { this . willInsertBlock . bind ( this , scrollback . uuid , idx ) }
817
852
willRemove = { this . willRemoveBlock . bind ( this , scrollback . uuid , idx ) }
818
853
willLoseFocus = { ( ) => this . doFocus ( scrollback ) }
819
854
isExperimental = { hasCommand ( _ ) && _ . isExperimental }
820
- isFocused = { sbidx === this . state . focusedIdx && isActive ( _ ) }
855
+ isFocused = {
856
+ // grab focus if this is the first active block in the scrollback
857
+ sbidx === this . state . focusedIdx && idx === this . findActiveBlock ( scrollback )
858
+ }
821
859
prefersTerminalPresentation = { isOk ( _ ) && _ . prefersTerminalPresentation }
822
860
isPartOfMiniSplit = { isMiniSplit }
823
861
isVisibleInMiniSplit = { idx === showThisIdxInMiniSplit || idx === nBlocks - 1 }
824
862
isWidthConstrained = { isWidthConstrained }
825
863
navigateTo = { this . navigateTo . bind ( this , scrollback ) }
826
864
ref = { c => {
827
- if ( isActive ( _ ) ) {
865
+ if ( idx === this . findActiveBlock ( scrollback ) ) {
828
866
// grab a ref to the active block, to help us maintain focus
829
867
scrollback . _activeBlock = c
830
868
}
0 commit comments