@@ -11,6 +11,7 @@ import { Lazy } from 'vs/base/common/lazy';
11
11
import { Disposable , DisposableStore , IDisposable , toDisposable } from 'vs/base/common/lifecycle' ;
12
12
import { ResourceMap } from 'vs/base/common/map' ;
13
13
import { Schemas } from 'vs/base/common/network' ;
14
+ import { isDefined } from 'vs/base/common/types' ;
14
15
import { URI } from 'vs/base/common/uri' ;
15
16
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService' ;
16
17
import { IEditorOptions } from 'vs/editor/common/config/editorOptions' ;
@@ -264,12 +265,16 @@ export class NotebookProviderInfoStore extends Disposable {
264
265
}
265
266
266
267
export class NotebookOutputRendererInfoStore {
267
- private readonly contributedRenderers = new Map < string , NotebookOutputRendererInfo > ( ) ;
268
+ private readonly contributedRenderers = new Map < /* rendererId */ string , NotebookOutputRendererInfo > ( ) ;
268
269
private readonly preferredMimetypeMemento : Memento ;
269
- private readonly preferredMimetype = new Lazy ( ( ) => this . preferredMimetypeMemento . getMemento ( StorageScope . WORKSPACE , StorageTarget . USER ) ) ;
270
+ private readonly preferredMimetype = new Lazy < { [ notebookType : string ] : { [ mimeType : string ] : /* rendererId */ string } } > (
271
+ ( ) => this . preferredMimetypeMemento . getMemento ( StorageScope . WORKSPACE , StorageTarget . USER ) ) ;
270
272
271
- constructor ( @IStorageService storageService : IStorageService ) {
272
- this . preferredMimetypeMemento = new Memento ( 'workbench.editor.notebook.preferredRenderer' , storageService ) ;
273
+ constructor (
274
+ @IStorageService storageService : IStorageService ,
275
+ @IWorkspaceTrustManagementService private readonly workspaceTrustManagementService : IWorkspaceTrustManagementService ,
276
+ ) {
277
+ this . preferredMimetypeMemento = new Memento ( 'workbench.editor.notebook.preferredRenderer2' , storageService ) ;
273
278
}
274
279
275
280
clear ( ) {
@@ -292,25 +297,65 @@ export class NotebookOutputRendererInfoStore {
292
297
}
293
298
294
299
/** Update and remember the preferred renderer for the given mimetype in this workspace */
295
- setPreferred ( mimeType : string , rendererId : string ) {
296
- this . preferredMimetype . getValue ( ) [ mimeType ] = rendererId ;
300
+ setPreferred ( notebookProviderInfo : NotebookProviderInfo , mimeType : string , rendererId : string ) {
301
+ const mementoObj = this . preferredMimetype . getValue ( ) ;
302
+ const forNotebook = mementoObj [ notebookProviderInfo . id ] ;
303
+ if ( forNotebook ) {
304
+ forNotebook [ mimeType ] = rendererId ;
305
+ } else {
306
+ mementoObj [ notebookProviderInfo . id ] = { [ mimeType ] : rendererId } ;
307
+ }
308
+
297
309
this . preferredMimetypeMemento . saveMemento ( ) ;
298
310
}
299
311
300
- getContributedRenderer ( mimeType : string , kernelProvides : readonly string [ ] | undefined ) : NotebookOutputRendererInfo [ ] {
301
- const preferred = this . preferredMimetype . getValue ( ) [ mimeType ] ;
302
- const possible = Array . from ( this . contributedRenderers . values ( ) )
303
- . map ( renderer => ( {
304
- renderer,
305
- score : kernelProvides === undefined
312
+ findBestRenderers ( notebookProviderInfo : NotebookProviderInfo | undefined , mimeType : string , kernelProvides : readonly string [ ] | undefined ) : IOrderedMimeType [ ] {
313
+
314
+ const enum ReuseOrder {
315
+ PreviouslySelected = 1 << 8 ,
316
+ SameExtensionAsNotebook = 2 << 8 ,
317
+ BuiltIn = 3 << 8 ,
318
+ OtherRenderer = 4 << 8
319
+ }
320
+
321
+ const preferred = notebookProviderInfo && this . preferredMimetype . getValue ( ) [ notebookProviderInfo . id ] ?. [ mimeType ] ;
322
+ const renderers : { ordered : IOrderedMimeType , score : number } [ ] = Array . from ( this . contributedRenderers . values ( ) )
323
+ . map ( renderer => {
324
+ const ownScore = kernelProvides === undefined
306
325
? renderer . matchesWithoutKernel ( mimeType )
307
- : renderer . matches ( mimeType , kernelProvides ) ,
308
- } ) )
309
- . sort ( ( a , b ) => a . score - b . score )
310
- . filter ( r => r . score !== NotebookRendererMatch . Never )
311
- . map ( r => r . renderer ) ;
326
+ : renderer . matches ( mimeType , kernelProvides ) ;
327
+
328
+ if ( ownScore === NotebookRendererMatch . Never ) {
329
+ return undefined ;
330
+ }
331
+
332
+ const reuseScore = preferred === renderer . id
333
+ ? ReuseOrder . PreviouslySelected
334
+ : renderer . extensionId . value === notebookProviderInfo ?. extension ?. value
335
+ ? ReuseOrder . SameExtensionAsNotebook
336
+ : ReuseOrder . BuiltIn ;
337
+ return {
338
+ ordered : { mimeType, rendererId : renderer . id , isTrusted : true } ,
339
+ score : reuseScore | ownScore ,
340
+ } ;
341
+ } ) . filter ( isDefined ) ;
342
+
343
+ if ( mimeTypeSupportedByCore ( mimeType ) ) {
344
+ renderers . push ( {
345
+ score : ReuseOrder . BuiltIn << 8 ,
346
+ ordered : {
347
+ mimeType,
348
+ rendererId : BUILTIN_RENDERER_ID ,
349
+ isTrusted : mimeTypeIsAlwaysSecure ( mimeType ) || this . workspaceTrustManagementService . isWorkspaceTrusted ( )
350
+ }
351
+ } ) ;
352
+ }
353
+
354
+ if ( renderers . length === 0 ) {
355
+ return [ { mimeType, rendererId : RENDERER_NOT_AVAILABLE , isTrusted : true } ] ;
356
+ }
312
357
313
- return preferred ? possible . sort ( ( a , b ) => ( a . id === preferred ? - 1 : 0 ) + ( b . id === preferred ? 1 : 0 ) ) : possible ;
358
+ return renderers . sort ( ( a , b ) => a . score - b . score ) . map ( r => r . ordered ) ;
314
359
}
315
360
}
316
361
@@ -376,7 +421,6 @@ export class NotebookService extends Disposable implements INotebookService {
376
421
@IInstantiationService private readonly _instantiationService : IInstantiationService ,
377
422
@ICodeEditorService private readonly _codeEditorService : ICodeEditorService ,
378
423
@IConfigurationService private readonly configurationService : IConfigurationService ,
379
- @IWorkspaceTrustManagementService private readonly workspaceTrustManagementService : IWorkspaceTrustManagementService ,
380
424
) {
381
425
super ( ) ;
382
426
@@ -569,8 +613,11 @@ export class NotebookService extends Disposable implements INotebookService {
569
613
return this . _notebookRenderersInfoStore . get ( rendererId ) ;
570
614
}
571
615
572
- updateMimePreferredRenderer ( mimeType : string , rendererId : string ) : void {
573
- this . _notebookRenderersInfoStore . setPreferred ( mimeType , rendererId ) ;
616
+ updateMimePreferredRenderer ( viewType : string , mimeType : string , rendererId : string ) : void {
617
+ const info = this . notebookProviderInfoStore . get ( viewType ) ;
618
+ if ( info ) {
619
+ this . _notebookRenderersInfoStore . setPreferred ( info , mimeType , rendererId ) ;
620
+ }
574
621
}
575
622
576
623
getRenderers ( ) : INotebookRendererInfo [ ] {
@@ -620,58 +667,9 @@ export class NotebookService extends Disposable implements INotebookService {
620
667
621
668
const coreDisplayOrder = this . _displayOrder ;
622
669
const sorted = sortMimeTypes ( mimeTypes , coreDisplayOrder ?. userOrder ?? [ ] , coreDisplayOrder ?. defaultOrder ?? [ ] ) ;
670
+ const notebookProviderInfo = this . notebookProviderInfoStore . get ( textModel . viewType ) ;
623
671
624
- const orderMimeTypes : IOrderedMimeType [ ] = [ ] ;
625
-
626
- sorted . forEach ( mimeType => {
627
- const handlers = this . _findBestMatchedRenderer ( mimeType , kernelProvides ) ;
628
-
629
- if ( handlers . length ) {
630
- const handler = handlers [ 0 ] ;
631
-
632
- orderMimeTypes . push ( {
633
- mimeType : mimeType ,
634
- rendererId : handler . id ,
635
- isTrusted : true
636
- } ) ;
637
-
638
- for ( let i = 1 ; i < handlers . length ; i ++ ) {
639
- orderMimeTypes . push ( {
640
- mimeType : mimeType ,
641
- rendererId : handlers [ i ] . id ,
642
- isTrusted : true
643
- } ) ;
644
- }
645
-
646
- if ( mimeTypeSupportedByCore ( mimeType ) ) {
647
- orderMimeTypes . push ( {
648
- mimeType : mimeType ,
649
- rendererId : BUILTIN_RENDERER_ID ,
650
- isTrusted : mimeTypeIsAlwaysSecure ( mimeType ) || this . workspaceTrustManagementService . isWorkspaceTrusted ( )
651
- } ) ;
652
- }
653
- } else {
654
- if ( mimeTypeSupportedByCore ( mimeType ) ) {
655
- orderMimeTypes . push ( {
656
- mimeType : mimeType ,
657
- rendererId : BUILTIN_RENDERER_ID ,
658
- isTrusted : mimeTypeIsAlwaysSecure ( mimeType ) || this . workspaceTrustManagementService . isWorkspaceTrusted ( )
659
- } ) ;
660
- } else {
661
- orderMimeTypes . push ( {
662
- mimeType : mimeType ,
663
- rendererId : RENDERER_NOT_AVAILABLE ,
664
- isTrusted : true
665
- } ) ;
666
- }
667
- }
668
- } ) ;
669
-
670
- return orderMimeTypes ;
671
- }
672
-
673
- private _findBestMatchedRenderer ( mimeType : string , kernelProvides : readonly string [ ] | undefined ) : readonly NotebookOutputRendererInfo [ ] {
674
- return this . _notebookRenderersInfoStore . getContributedRenderer ( mimeType , kernelProvides ) ;
672
+ return sorted . flatMap ( mimeType => this . _notebookRenderersInfoStore . findBestRenderers ( notebookProviderInfo , mimeType , kernelProvides ) ) ;
675
673
}
676
674
677
675
getContributedNotebookTypes ( resource ?: URI ) : readonly NotebookProviderInfo [ ] {
0 commit comments