@@ -38,6 +38,10 @@ type KernelPick = IQuickPickItem & { kernel: INotebookKernel };
38
38
function isKernelPick ( item : QuickPickInput < IQuickPickItem > ) : item is KernelPick {
39
39
return 'kernel' in item ;
40
40
}
41
+ type GroupedKernelsPick = IQuickPickItem & { kernels : INotebookKernel [ ] ; source : string } ;
42
+ function isGroupedKernelsPick ( item : QuickPickInput < IQuickPickItem > ) : item is GroupedKernelsPick {
43
+ return 'kernels' in item ;
44
+ }
41
45
type SourcePick = IQuickPickItem & { action : ISourceAction } ;
42
46
function isSourcePick ( item : QuickPickInput < IQuickPickItem > ) : item is SourcePick {
43
47
return 'action' in item ;
@@ -50,7 +54,7 @@ type KernelSourceQuickPickItem = IQuickPickItem & { command: Command };
50
54
function isKernelSourceQuickPickItem ( item : IQuickPickItem ) : item is KernelSourceQuickPickItem {
51
55
return 'command' in item ;
52
56
}
53
- type KernelQuickPickItem = IQuickPickItem | InstallExtensionPick | KernelPick | SourcePick | KernelSourceQuickPickItem ;
57
+ type KernelQuickPickItem = IQuickPickItem | InstallExtensionPick | KernelPick | GroupedKernelsPick | SourcePick | KernelSourceQuickPickItem ;
54
58
const KERNEL_PICKER_UPDATE_DEBOUNCE = 200 ;
55
59
56
60
export type KernelQuickPickContext =
@@ -63,8 +67,8 @@ export interface IKernelPickerStrategy {
63
67
showQuickPick ( editor : IActiveNotebookEditor , wantedKernelId ?: string ) : Promise < boolean > ;
64
68
}
65
69
66
- function toQuickPick ( kernel : INotebookKernel , selected : INotebookKernel | undefined ) {
67
- const res = < KernelPick > {
70
+ function toKernelQuickPick ( kernel : INotebookKernel , selected : INotebookKernel | undefined ) {
71
+ const res : KernelPick = {
68
72
kernel,
69
73
picked : kernel . id === selected ?. id ,
70
74
label : kernel . label ,
@@ -417,7 +421,7 @@ export class KernelPickerFlatStrategy extends KernelPickerStrategyBase {
417
421
418
422
// Next display all of the kernels not marked as hidden grouped by categories or extensions.
419
423
// If we don't have a kind, always display those at the bottom.
420
- const picks = all . filter ( item => ( ! suggestions . includes ( item ) && ! hidden . includes ( item ) ) ) . map ( kernel => toQuickPick ( kernel , selected ) ) ;
424
+ const picks = all . filter ( item => ( ! suggestions . includes ( item ) && ! hidden . includes ( item ) ) ) . map ( kernel => toKernelQuickPick ( kernel , selected ) ) ;
421
425
const kernelsPerCategory = groupBy ( picks , ( a , b ) => compareIgnoreCase ( a . kernel . kind || 'z' , b . kernel . kind || 'z' ) ) ;
422
426
kernelsPerCategory . forEach ( items => {
423
427
quickPickItems . push ( {
@@ -461,15 +465,15 @@ export class KernelPickerFlatStrategy extends KernelPickerStrategyBase {
461
465
} ) ;
462
466
463
467
// The title is already set to "Selected" so we don't need to set it again in description, thus passing in `undefined`.
464
- quickPickItems . push ( toQuickPick ( suggestions [ 0 ] , undefined ) ) ;
468
+ quickPickItems . push ( toKernelQuickPick ( suggestions [ 0 ] , undefined ) ) ;
465
469
return ;
466
470
}
467
471
468
472
quickPickItems . push ( {
469
473
type : 'separator' ,
470
474
label : localize ( 'suggestedKernels' , "Suggested" )
471
475
} ) ;
472
- quickPickItems . push ( ...suggestions . map ( kernel => toQuickPick ( kernel , selected ) ) ) ;
476
+ quickPickItems . push ( ...suggestions . map ( kernel => toKernelQuickPick ( kernel , selected ) ) ) ;
473
477
}
474
478
475
479
static updateKernelStatusAction ( notebook : NotebookTextModel , action : IAction , notebookKernelService : INotebookKernelService , scopedContextKeyService ?: IContextKeyService ) {
@@ -543,7 +547,7 @@ export class KernelPickerMRUStrategy extends KernelPickerStrategyBase {
543
547
@IExtensionsWorkbenchService _extensionWorkbenchService : IExtensionsWorkbenchService ,
544
548
@IExtensionService _extensionService : IExtensionService ,
545
549
@ICommandService _commandService : ICommandService ,
546
- @INotebookKernelHistoryService private readonly _notebookKernelHistoryService : INotebookKernelHistoryService ,
550
+ @INotebookKernelHistoryService private readonly _notebookKernelHistoryService : INotebookKernelHistoryService
547
551
548
552
) {
549
553
super (
@@ -564,7 +568,7 @@ export class KernelPickerMRUStrategy extends KernelPickerStrategyBase {
564
568
let previousKind = '' ;
565
569
566
570
if ( matchResult . selected ) {
567
- const kernelItem = toQuickPick ( matchResult . selected , matchResult . selected ) ;
571
+ const kernelItem = toKernelQuickPick ( matchResult . selected , matchResult . selected ) ;
568
572
const kind = matchResult . selected . kind || '' ;
569
573
if ( kind ) {
570
574
previousKind = kind ;
@@ -573,7 +577,7 @@ export class KernelPickerMRUStrategy extends KernelPickerStrategyBase {
573
577
quickPickItems . push ( kernelItem ) ;
574
578
}
575
579
576
- matchResult . suggestions . filter ( kernel => kernel . id !== matchResult . selected ?. id ) . map ( kernel => toQuickPick ( kernel , matchResult . selected ) )
580
+ matchResult . suggestions . filter ( kernel => kernel . id !== matchResult . selected ?. id ) . map ( kernel => toKernelQuickPick ( kernel , matchResult . selected ) )
577
581
. forEach ( kernel => {
578
582
const kind = kernel . kernel . kind || '' ;
579
583
if ( kind && kind !== previousKind ) {
@@ -663,6 +667,9 @@ export class KernelPickerMRUStrategy extends KernelPickerStrategyBase {
663
667
} else if ( isKernelPick ( quickPick . selectedItems [ 0 ] ) ) {
664
668
await this . _selecteKernel ( notebook , quickPick . selectedItems [ 0 ] . kernel ) ;
665
669
resolve ( true ) ;
670
+ } else if ( isGroupedKernelsPick ( quickPick . selectedItems [ 0 ] ) ) {
671
+ await this . _selectOneKernel ( notebook , quickPick . selectedItems [ 0 ] . source , quickPick . selectedItems [ 0 ] . kernels ) ;
672
+ resolve ( true ) ;
666
673
} else if ( isSourcePick ( quickPick . selectedItems [ 0 ] ) ) {
667
674
// selected explicilty, it should trigger the execution?
668
675
quickPick . selectedItems [ 0 ] . action . runAction ( ) ;
@@ -674,11 +681,26 @@ export class KernelPickerMRUStrategy extends KernelPickerStrategyBase {
674
681
quickPick . busy = false ;
675
682
const matchResult = this . _getMatchingResult ( notebook ) ;
676
683
const others = matchResult . all . filter ( item => item . extension . value !== JUPYTER_EXTENSION_ID ) ;
677
- quickPickItems . push ( ...others . map ( kernel => ( {
678
- label : kernel . label ,
679
- detail : kernel . extension . value ,
680
- kernel
681
- } ) ) ) ;
684
+
685
+ // group controllers by extension
686
+ for ( const group of groupBy ( others , ( a , b ) => a . extension . value === b . extension . value ? 0 : 1 ) ) {
687
+ const extension = this . _extensionService . extensions . find ( extension => extension . identifier . value === group [ 0 ] . extension . value ) ;
688
+ const source = extension ?. description ?? group [ 0 ] . extension . value ;
689
+ if ( group . length > 1 ) {
690
+ quickPickItems . push ( {
691
+ label : source ,
692
+ detail : localize ( 'selectKernelFromExtensionDetail' , "Kernels: {0}" , group . map ( kernel => kernel . label ) . join ( ', ' ) ) ,
693
+ kernels : group
694
+ } ) ;
695
+ } else {
696
+ quickPickItems . push ( {
697
+ label : group [ 0 ] . label ,
698
+ detail : source ,
699
+ kernel : group [ 0 ]
700
+ } ) ;
701
+ }
702
+ }
703
+
682
704
const validActions = actions . filter ( action => action . command ) ;
683
705
684
706
quickPickItems . push ( ...validActions . map ( action => {
@@ -710,6 +732,30 @@ export class KernelPickerMRUStrategy extends KernelPickerStrategyBase {
710
732
} ) ;
711
733
}
712
734
735
+ private async _selectOneKernel ( notebook : NotebookTextModel , source : string , kernels : INotebookKernel [ ] ) {
736
+ const quickPickItems : QuickPickInput < KernelPick > [ ] = kernels . map ( kernel => toKernelQuickPick ( kernel , undefined ) ) ;
737
+ const quickPick = this . _quickInputService . createQuickPick < KernelQuickPickItem > ( ) ;
738
+ quickPick . items = quickPickItems ;
739
+ quickPick . canSelectMany = false ;
740
+
741
+ quickPick . title = localize ( 'selectKernelFromExtension' , "Select Kernel from {0}" , source ) ;
742
+
743
+ quickPick . onDidAccept ( async ( ) => {
744
+ if ( quickPick . selectedItems && quickPick . selectedItems . length > 0 && isKernelPick ( quickPick . selectedItems [ 0 ] ) ) {
745
+ await this . _selecteKernel ( notebook , quickPick . selectedItems [ 0 ] . kernel ) ;
746
+ }
747
+
748
+ quickPick . hide ( ) ;
749
+ quickPick . dispose ( ) ;
750
+ } ) ;
751
+
752
+ quickPick . onDidHide ( ( ) => {
753
+ quickPick . dispose ( ) ;
754
+ } ) ;
755
+
756
+ quickPick . show ( ) ;
757
+ }
758
+
713
759
private async _executeCommand < T > ( notebook : NotebookTextModel , command : string | Command ) : Promise < T | undefined | void > {
714
760
const id = typeof command === 'string' ? command : command . id ;
715
761
const args = typeof command === 'string' ? [ ] : command . arguments ?? [ ] ;
0 commit comments