@@ -112,6 +112,7 @@ export class Workspace {
112
112
#readonly = false ; // TODO do we need workspaces for readonly stuff?
113
113
#files = $state . raw < Item [ ] > ( [ ] ) ;
114
114
#current = $state . raw ( ) as File ;
115
+ #vim = $state ( false ) ;
115
116
116
117
#handlers = {
117
118
hover : new Set < ( pos : number | null ) => void > ( ) ,
@@ -279,23 +280,10 @@ export class Workspace {
279
280
if ( this . #view) throw new Error ( 'view is already linked' ) ;
280
281
this . #view = view ;
281
282
282
- view . setState ( this . #get_state( untrack ( ( ) => this . #current) ) ) ;
283
-
284
- let should_install_vim = localStorage . getItem ( 'vim' ) === 'true' ;
285
-
286
- const q = new URLSearchParams ( location . search ) ;
287
- if ( q . has ( 'vim' ) ) {
288
- should_install_vim = q . get ( 'vim' ) === 'true' ;
289
- localStorage . setItem ( 'vim' , should_install_vim . toString ( ) ) ;
290
- }
291
-
292
- if ( should_install_vim ) {
293
- const { vim } = await import ( '@replit/codemirror-vim' ) ;
294
-
295
- this . #view?. dispatch ( {
296
- effects : vim_mode . reconfigure ( vim ( ) )
297
- } ) ;
298
- }
283
+ untrack ( ( ) => {
284
+ view . setState ( this . #get_state( untrack ( ( ) => this . #current) ) ) ;
285
+ this . vim = localStorage . getItem ( 'vim' ) === 'true' ;
286
+ } ) ;
299
287
}
300
288
301
289
move ( from : Item , to : Item ) {
@@ -476,6 +464,44 @@ export class Workspace {
476
464
}
477
465
}
478
466
467
+ get vim ( ) {
468
+ return this . #vim;
469
+ }
470
+
471
+ set vim ( value ) {
472
+ this . #toggle_vim( value ) ;
473
+ }
474
+
475
+ async #toggle_vim( value : boolean ) {
476
+ this . #vim = value ;
477
+
478
+ localStorage . setItem ( 'vim' , String ( value ) ) ;
479
+
480
+ // @ts -expect-error jfc CodeMirror is a struggle
481
+ let vim_extension_index = default_extensions . findIndex ( ( ext ) => ext . compartment === vim_mode ) ;
482
+
483
+ let extension : any = [ ] ;
484
+
485
+ if ( value ) {
486
+ const { vim } = await import ( '@replit/codemirror-vim' ) ;
487
+ extension = vim ( ) ;
488
+ }
489
+
490
+ default_extensions [ vim_extension_index ] = vim_mode . of ( extension ) ;
491
+
492
+ this . #view?. dispatch ( {
493
+ effects : vim_mode . reconfigure ( extension )
494
+ } ) ;
495
+
496
+ // update all the other states
497
+ for ( const file of this . #files) {
498
+ if ( file . type !== 'file' ) continue ;
499
+ if ( file === this . #current) continue ;
500
+
501
+ this . states . set ( file . name , this . #create_state( file ) ) ;
502
+ }
503
+ }
504
+
479
505
#create_directories( item : Item ) {
480
506
// create intermediate directories as necessary
481
507
const parts = item . name . split ( '/' ) ;
@@ -497,9 +523,10 @@ export class Workspace {
497
523
}
498
524
499
525
#get_state( file : File ) {
500
- let state = this . states . get ( file . name ) ;
501
- if ( state ) return state ;
526
+ return this . states . get ( file . name ) ?? this . #create_state ( file ) ;
527
+ }
502
528
529
+ #create_state( file : File ) {
503
530
const extensions = [
504
531
...default_extensions ,
505
532
EditorState . readOnly . of ( this . #readonly) ,
@@ -573,7 +600,7 @@ export class Workspace {
573
600
break ;
574
601
}
575
602
576
- state = EditorState . create ( {
603
+ const state = EditorState . create ( {
577
604
doc : file . contents ,
578
605
extensions
579
606
} ) ;
0 commit comments