Skip to content

Commit 8007c63

Browse files
Kernel mru picker preparation (microsoft#166513)
* MRU skeleton * Kernel Source Provider * filter * register provider in exthost * Misc changes * Revert to suggestions * non jupyter controllers * Add ability to select a kernel * show extension name in detail. * 💄 * Move strategies out. * Back button * First arg be the notebook document * 💄 * Update kernel status * Show progress in MRU * remove separator header * Allow selecting 3rd party controllers * Misc * Fix spinner * Add separators in kernel picker * Update kernel select title. * Prep for MRU. Co-authored-by: Don Jayamanne <[email protected]>
1 parent 94a1ec7 commit 8007c63

12 files changed

+924
-536
lines changed

src/vs/workbench/api/browser/mainThreadNotebookKernels.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { isNonEmptyArray } from 'vs/base/common/arrays';
7+
import { CancellationToken } from 'vs/base/common/cancellation';
78
import { onUnexpectedError } from 'vs/base/common/errors';
89
import { Emitter, Event } from 'vs/base/common/event';
910
import { combinedDisposable, DisposableMap, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
@@ -15,7 +16,7 @@ import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/ext
1516
import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
1617
import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService';
1718
import { INotebookCellExecution, INotebookExecutionStateService } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
18-
import { INotebookKernel, INotebookKernelChangeEvent, INotebookKernelDetectionTask, INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
19+
import { IKernelSourceActionProvider, INotebookKernel, INotebookKernelChangeEvent, INotebookKernelDetectionTask, INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
1920
import { SerializableObjectWithBuffers } from 'vs/workbench/services/extensions/common/proxyIdentifier';
2021
import { ExtHostContext, ExtHostNotebookKernelsShape, ICellExecuteUpdateDto, ICellExecutionCompleteDto, INotebookKernelDto2, MainContext, MainThreadNotebookKernelsShape } from '../common/extHost.protocol';
2122
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
@@ -113,6 +114,7 @@ export class MainThreadNotebookKernels implements MainThreadNotebookKernelsShape
113114

114115
private readonly _kernels = new Map<number, [kernel: MainThreadKernel, registraion: IDisposable]>();
115116
private readonly _kernelDetectionTasks = new Map<number, [task: MainThreadKernelDetectionTask, registraion: IDisposable]>();
117+
private readonly _kernelSourceActionProviders = new Map<number, [provider: IKernelSourceActionProvider, registraion: IDisposable]>();
116118
private readonly _proxy: ExtHostNotebookKernelsShape;
117119

118120
private readonly _executions = new Map<number, INotebookCellExecution>();
@@ -309,4 +311,25 @@ export class MainThreadNotebookKernels implements MainThreadNotebookKernelsShape
309311
this._kernelDetectionTasks.delete(handle);
310312
}
311313
}
314+
315+
// --- notebook kernel source action provider
316+
317+
async $addKernelSourceActionProvider(handle: number, notebookType: string): Promise<void> {
318+
const kernelSourceActionProvider: IKernelSourceActionProvider = {
319+
viewType: notebookType,
320+
provideKernelSourceActions: async () => {
321+
return this._proxy.$provideKernelSourceActions(handle, CancellationToken.None);
322+
}
323+
};
324+
const registration = this._notebookKernelService.registerKernelSourceActionProvider(notebookType, kernelSourceActionProvider);
325+
this._kernelSourceActionProviders.set(handle, [kernelSourceActionProvider, registration]);
326+
}
327+
328+
$removeKernelSourceActionProvider(handle: number): void {
329+
const tuple = this._kernelSourceActionProviders.get(handle);
330+
if (tuple) {
331+
tuple[1].dispose();
332+
this._kernelSourceActionProviders.delete(handle);
333+
}
334+
}
312335
}

src/vs/workbench/api/common/extHost.api.impl.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
11521152
checkProposedApiEnabled(extension, 'notebookKernelSource');
11531153
return extHostNotebookKernels.createNotebookControllerDetectionTask(extension, notebookType);
11541154
},
1155+
registerKernelSourceActionProvider(notebookType: string, provider: vscode.NotebookKernelSourceActionProvider) {
1156+
checkProposedApiEnabled(extension, 'notebookKernelSource');
1157+
return extHostNotebookKernels.registerKernelSourceActionProvider(extension, notebookType, provider);
1158+
},
11551159
onDidChangeNotebookCellExecutionState(listener, thisArgs?, disposables?) {
11561160
checkProposedApiEnabled(extension, 'notebookCellExecutionState');
11571161
return extHostNotebookKernels.onDidChangeNotebookCellExecutionState(listener, thisArgs, disposables);
@@ -1345,6 +1349,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
13451349
NotebookControllerAffinity: extHostTypes.NotebookControllerAffinity,
13461350
NotebookControllerAffinity2: extHostTypes.NotebookControllerAffinity2,
13471351
NotebookEdit: extHostTypes.NotebookEdit,
1352+
NotebookKernelSourceAction: extHostTypes.NotebookKernelSourceAction,
13481353
PortAttributes: extHostTypes.PortAttributes,
13491354
LinkedEditingRanges: extHostTypes.LinkedEditingRanges,
13501355
TestResultState: extHostTypes.TestResultState,

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,9 @@ export interface MainThreadNotebookKernelsShape extends IDisposable {
10471047

10481048
$addKernelDetectionTask(handle: number, notebookType: string): Promise<void>;
10491049
$removeKernelDetectionTask(handle: number): void;
1050+
1051+
$addKernelSourceActionProvider(handle: number, notebookType: string): Promise<void>;
1052+
$removeKernelSourceActionProvider(handle: number): void;
10501053
}
10511054

10521055
export interface MainThreadNotebookRenderersShape extends IDisposable {
@@ -2136,6 +2139,7 @@ export interface ExtHostNotebookKernelsShape {
21362139
$cancelCells(handle: number, uri: UriComponents, handles: number[]): Promise<void>;
21372140
$acceptKernelMessageFromRenderer(handle: number, editorId: string, message: any): void;
21382141
$cellExecutionChanged(uri: UriComponents, cellHandle: number, state: notebookCommon.NotebookCellExecutionState | undefined): void;
2142+
$provideKernelSourceActions(handle: number, token: CancellationToken): Promise<notebookCommon.INotebookKernelSourceAction[]>;
21392143
}
21402144

21412145
export interface ExtHostInteractiveShape {

src/vs/workbench/api/common/extHostNotebookKernels.ts

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55

66
import { asArray } from 'vs/base/common/arrays';
77
import { DeferredPromise, timeout } from 'vs/base/common/async';
8-
import { CancellationTokenSource } from 'vs/base/common/cancellation';
8+
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
99
import { Emitter } from 'vs/base/common/event';
10-
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
10+
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
1111
import { ResourceMap } from 'vs/base/common/map';
1212
import { URI, UriComponents } from 'vs/base/common/uri';
1313
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
1414
import { ILogService } from 'vs/platform/log/common/log';
15+
import { Cache } from 'vs/workbench/api/common/cache';
1516
import { ExtHostNotebookKernelsShape, ICellExecuteUpdateDto, IMainContext, INotebookKernelDto2, MainContext, MainThreadNotebookKernelsShape, NotebookOutputDto } from 'vs/workbench/api/common/extHost.protocol';
1617
import { ApiCommand, ApiCommandArgument, ApiCommandResult, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
1718
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
@@ -20,7 +21,7 @@ import { ExtHostCell } from 'vs/workbench/api/common/extHostNotebookDocument';
2021
import * as extHostTypeConverters from 'vs/workbench/api/common/extHostTypeConverters';
2122
import { NotebookCellExecutionState as ExtHostNotebookCellExecutionState, NotebookCellOutput, NotebookControllerAffinity2 } from 'vs/workbench/api/common/extHostTypes';
2223
import { asWebviewUri } from 'vs/workbench/contrib/webview/common/webview';
23-
import { NotebookCellExecutionState } from 'vs/workbench/contrib/notebook/common/notebookCommon';
24+
import { INotebookKernelSourceAction, NotebookCellExecutionState } from 'vs/workbench/contrib/notebook/common/notebookCommon';
2425
import { CellExecutionUpdateType } from 'vs/workbench/contrib/notebook/common/notebookExecutionService';
2526
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
2627
import { SerializableObjectWithBuffers } from 'vs/workbench/services/extensions/common/proxyIdentifier';
@@ -47,6 +48,10 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
4748
private _kernelDetectionTask = new Map<number, vscode.NotebookControllerDetectionTask>();
4849
private _kernelDetectionTaskHandlePool: number = 0;
4950

51+
private _kernelSourceActionProviders = new Map<number, vscode.NotebookKernelSourceActionProvider>();
52+
private _kernelSourceActionProviderHandlePool: number = 0;
53+
private _kernelSourceActionProviderCache = new Cache<IDisposable>('NotebookKernelSourceActionProviderCache');
54+
5055
private readonly _kernelData = new Map<number, IKernelData>();
5156
private _handlePool: number = 0;
5257

@@ -292,6 +297,33 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
292297
return detectionTask;
293298
}
294299

300+
registerKernelSourceActionProvider(extension: IExtensionDescription, viewType: string, provider: vscode.NotebookKernelSourceActionProvider) {
301+
const handle = this._kernelSourceActionProviderHandlePool++;
302+
const that = this;
303+
304+
this._kernelSourceActionProviders.set(handle, provider);
305+
this._logService.trace(`NotebookKernelSourceActionProvider[${handle}], CREATED by ${extension.identifier.value}`);
306+
this._proxy.$addKernelSourceActionProvider(handle, viewType);
307+
308+
return {
309+
dispose: () => {
310+
this._kernelSourceActionProviders.delete(handle);
311+
that._proxy.$removeKernelSourceActionProvider(handle);
312+
}
313+
};
314+
}
315+
316+
async $provideKernelSourceActions(handle: number, token: CancellationToken): Promise<INotebookKernelSourceAction[]> {
317+
const provider = this._kernelSourceActionProviders.get(handle);
318+
if (provider) {
319+
const disposables = new DisposableStore();
320+
this._kernelSourceActionProviderCache.add([disposables]);
321+
const ret = await provider.provideNotebookKernelSourceActions(token);
322+
return (ret ?? []).map(item => extHostTypeConverters.NotebookKernelSourceAction.from(item, this._commands.converter, disposables));
323+
}
324+
return [];
325+
}
326+
295327
$acceptNotebookAssociation(handle: number, uri: UriComponents, value: boolean): void {
296328
const obj = this._kernelData.get(handle);
297329
if (obj) {

src/vs/workbench/api/common/extHostTypeConverters.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,19 @@ export namespace NotebookStatusBarItem {
17051705
}
17061706
}
17071707

1708+
export namespace NotebookKernelSourceAction {
1709+
export function from(item: vscode.NotebookKernelSourceAction, commandsConverter: Command.ICommandsConverter, disposables: DisposableStore): notebooks.INotebookKernelSourceAction {
1710+
const command = typeof item.command === 'string' ? { title: '', command: item.command } : item.command;
1711+
1712+
return {
1713+
command: commandsConverter.toInternal(command, disposables),
1714+
label: item.label,
1715+
description: item.description,
1716+
detail: item.detail
1717+
};
1718+
}
1719+
}
1720+
17081721
export namespace NotebookDocumentContentOptions {
17091722
export function from(options: vscode.NotebookDocumentContentOptions | undefined): notebooks.TransientOptions {
17101723
return {

src/vs/workbench/api/common/extHostTypes.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3617,6 +3617,15 @@ export class NotebookRendererScript {
36173617
}
36183618
}
36193619

3620+
export class NotebookKernelSourceAction {
3621+
description?: string;
3622+
detail?: string;
3623+
command?: vscode.Command;
3624+
constructor(
3625+
public label: string
3626+
) { }
3627+
}
3628+
36203629
//#endregion
36213630

36223631
//#region Timeline

src/vs/workbench/contrib/notebook/browser/services/notebookKernelServiceImpl.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66
import { Event, Emitter } from 'vs/base/common/event';
77
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
8-
import { INotebookTextModel } from 'vs/workbench/contrib/notebook/common/notebookCommon';
9-
import { INotebookKernel, ISelectedNotebooksChangeEvent, INotebookKernelMatchResult, INotebookKernelService, INotebookTextModelLike, ISourceAction, INotebookSourceActionChangeEvent, INotebookKernelDetectionTask } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
8+
import { INotebookKernelSourceAction, INotebookTextModel } from 'vs/workbench/contrib/notebook/common/notebookCommon';
9+
import { INotebookKernel, ISelectedNotebooksChangeEvent, INotebookKernelMatchResult, INotebookKernelService, INotebookTextModelLike, ISourceAction, INotebookSourceActionChangeEvent, INotebookKernelDetectionTask, IKernelSourceActionProvider } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
1010
import { LRUCache, ResourceMap } from 'vs/base/common/map';
1111
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
1212
import { URI } from 'vs/base/common/uri';
@@ -107,6 +107,7 @@ export class NotebookKernelService extends Disposable implements INotebookKernel
107107
private readonly _kernelSources = new Map<string, IKernelInfoCache>();
108108
private readonly _kernelDetectionTasks = new Map<string, INotebookKernelDetectionTask[]>();
109109
private readonly _onDidChangeKernelDetectionTasks = this._register(new Emitter<string>());
110+
private readonly _kernelSourceActionProviders = new Map<string, IKernelSourceActionProvider[]>();
110111

111112
readonly onDidChangeSelectedNotebooks: Event<ISelectedNotebooksChangeEvent> = this._onDidChangeNotebookKernelBinding.event;
112113
readonly onDidAddKernel: Event<INotebookKernel> = this._onDidAddKernel.event;
@@ -366,4 +367,31 @@ export class NotebookKernelService extends Disposable implements INotebookKernel
366367
getKernelDetectionTasks(notebook: INotebookTextModelLike): INotebookKernelDetectionTask[] {
367368
return this._kernelDetectionTasks.get(notebook.viewType) ?? [];
368369
}
370+
371+
registerKernelSourceActionProvider(viewType: string, provider: IKernelSourceActionProvider): IDisposable {
372+
const providers = this._kernelSourceActionProviders.get(viewType) ?? [];
373+
providers.push(provider);
374+
this._kernelSourceActionProviders.set(viewType, providers);
375+
376+
return toDisposable(() => {
377+
const providers = this._kernelSourceActionProviders.get(viewType) ?? [];
378+
const idx = providers.indexOf(provider);
379+
if (idx >= 0) {
380+
providers.splice(idx, 1);
381+
this._kernelSourceActionProviders.set(viewType, providers);
382+
}
383+
});
384+
}
385+
386+
/**
387+
* Get kernel source actions from providers
388+
*/
389+
getKernelSourceActions2(notebook: INotebookTextModelLike): Promise<INotebookKernelSourceAction[]> {
390+
const viewType = notebook.viewType;
391+
const providers = this._kernelSourceActionProviders.get(viewType) ?? [];
392+
const promises = providers.map(provider => provider.provideKernelSourceActions());
393+
return Promise.all(promises).then(actions => {
394+
return actions.reduce((a, b) => a.concat(b), []);
395+
});
396+
}
369397
}

0 commit comments

Comments
 (0)