@@ -36,7 +36,10 @@ import { AceMouseEvent, HighlightedLines, Position } from './EditorTypes';
3636// TODO: Should further refactor into EditorBase + different variants.
3737// Ideally, hooks should be specified by the parent component instead.
3838import type { SharedbAceUser } from '@sourceacademy/sharedb-ace/types' ;
39+ import { flagConductorEnable } from 'src/features/conductor/flagConductorEnable' ;
3940import { ExternalLibraryName } from '../application/types/ExternalTypes' ;
41+ import { useFeature } from '../featureFlags/useFeature' ;
42+ import { useTypedSelector } from '../utils/Hooks' ;
4043import useHighlighting from './UseHighlighting' ;
4144import useNavigation from './UseNavigation' ;
4245import useRefactor from './UseRefactor' ;
@@ -72,6 +75,7 @@ type EditorStateProps = {
7275 sourceVariant ?: Variant ;
7376 hooks ?: EditorHook [ ] ;
7477 editorBinding ?: EditorBinding ;
78+ mode ?: string ;
7579 setUsers ?: React . Dispatch < React . SetStateAction < Record < string , SharedbAceUser > > > ;
7680 // TODO: Handle changing of external library
7781 updateLanguageCallback ?: ( sublanguage : SALanguage , e : any ) => void ;
@@ -471,6 +475,67 @@ const EditorBase = memo((props: EditorProps & LocalStateProps) => {
471475 }
472476 } ;
473477
478+ const conductorEnabled = useFeature ( flagConductorEnable ) ;
479+ const selectedEvaluatorId = useTypedSelector ( s => s . languageDirectory . selectedEvaluatorId ) ! ;
480+ useEffect ( ( ) => {
481+ if ( ! conductorEnabled || ! reactAceRef . current || ! selectedEvaluatorId ) {
482+ return ;
483+ }
484+
485+ const editor = reactAceRef . current . editor ;
486+ const modeId = `ace/mode/${ selectedEvaluatorId } ` ;
487+ let modeChangeUnsub : ( ( ) => void ) | undefined ;
488+ let pollHandle : ReturnType < typeof setInterval > | undefined ;
489+
490+ const apply = ( session : any ) => {
491+ let modeModule : any ;
492+ try {
493+ modeModule = acequire ( modeId ) ;
494+ } catch {
495+ return false ;
496+ }
497+ if ( ! modeModule ?. Mode ) return false ;
498+ if ( ( session . getMode ( ) as any ) . $id === modeId ) return true ;
499+ session . setMode ( new modeModule . Mode ( ) ) ;
500+ return true ;
501+ } ;
502+
503+ const attachToSession = ( session : any ) => {
504+ modeChangeUnsub ?.( ) ;
505+ if ( pollHandle ) clearInterval ( pollHandle ) ;
506+
507+ const onChangeMode = ( ) => {
508+ if ( ( session . getMode ( ) as any ) . $id !== modeId ) {
509+ apply ( session ) ;
510+ }
511+ } ;
512+ session . on ( 'changeMode' , onChangeMode ) ;
513+ modeChangeUnsub = ( ) => session . off ( 'changeMode' , onChangeMode ) ;
514+
515+ if ( ! apply ( session ) ) {
516+ pollHandle = setInterval ( ( ) => {
517+ if ( apply ( session ) ) {
518+ clearInterval ( pollHandle ) ;
519+ pollHandle = undefined ;
520+ }
521+ } , 200 ) ;
522+ }
523+ } ;
524+
525+ attachToSession ( editor . getSession ( ) ) ;
526+
527+ const onChangeSession = ( e : any ) => {
528+ attachToSession ( e . session ) ;
529+ } ;
530+ editor . on ( 'changeSession' , onChangeSession ) ;
531+
532+ return ( ) => {
533+ modeChangeUnsub ?.( ) ;
534+ if ( pollHandle ) clearInterval ( pollHandle ) ;
535+ editor . off ( 'changeSession' , onChangeSession ) ;
536+ } ;
537+ } , [ conductorEnabled , selectedEvaluatorId ] ) ;
538+
474539 const aceEditorProps : IAceEditorProps = {
475540 className : 'react-ace' ,
476541 editorProps : {
@@ -480,7 +545,9 @@ const EditorBase = memo((props: EditorProps & LocalStateProps) => {
480545 fontSize : 17 ,
481546 height : '100%' ,
482547 highlightActiveLine : false ,
483- mode : getModeString ( sourceChapter , sourceVariant , externalLibraryName ) ,
548+ mode : conductorEnabled
549+ ? 'text'
550+ : getModeString ( sourceChapter , sourceVariant , externalLibraryName ) ,
484551 theme : 'source' ,
485552 value : props . editorValue ,
486553 width : '100%' ,
0 commit comments