diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index 4b8dcf46709..dfcaefa1ada 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -1822,6 +1822,7 @@ declare module 'vscode' { } export interface NotebookKernel { + readonly id: string; label: string; description?: string; isPreferred?: boolean; @@ -1890,8 +1891,7 @@ declare module 'vscode' { */ export function createConcatTextDocument(notebook: NotebookDocument, selector?: DocumentSelector): NotebookConcatTextDocument; - export let activeNotebookKernel: NotebookKernel | undefined; - export const onDidChangeActiveNotebookKernel: Event; + export const onDidChangeActiveNotebookKernel: Event<{ document: NotebookDocument, kernel: NotebookKernel | undefined }>; } //#endregion diff --git a/src/vs/workbench/api/browser/mainThreadNotebook.ts b/src/vs/workbench/api/browser/mainThreadNotebook.ts index 2b63e4e286e..734d1da9521 100644 --- a/src/vs/workbench/api/browser/mainThreadNotebook.ts +++ b/src/vs/workbench/api/browser/mainThreadNotebook.ts @@ -308,6 +308,10 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo this._updateState(); })); + this._register(this._notebookService.onDidChangeNotebookActiveKernel(e => { + this._proxy.$acceptNotebookActiveKernelChange(e); + })); + const updateOrder = () => { let userOrder = this.configurationService.getValue('notebook.displayOrder'); this._proxy.$acceptDisplayOrder({ @@ -464,8 +468,14 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo const provider = this._notebookService.registerNotebookKernelProvider({ onDidChangeKernels: emitter.event, selector: documentFilter, - provideKernels: (uri: URI, token: CancellationToken) => { - return that._proxy.$provideNotebookKernels(handle, uri, token); + provideKernels: async (uri: URI, token: CancellationToken) => { + const kernels = await that._proxy.$provideNotebookKernels(handle, uri, token); + return kernels.map(kernel => { + return { + ...kernel, + providerHandle: handle + }; + }); }, resolveKernel: (editorId: string, uri: URI, kernelId: string, token: CancellationToken) => { return that._proxy.$resolveNotebookKernel(handle, editorId, uri, kernelId, token); diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index b343f44f2d8..61a58ff90a8 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -933,10 +933,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I checkProposedApiEnabled(extension); return extHostNotebook.onDidChangeVisibleNotebookEditors; }, - get activeNotebookKernel() { - checkProposedApiEnabled(extension); - return extHostNotebook.activeNotebookKernel; - }, get onDidChangeActiveNotebookKernel() { checkProposedApiEnabled(extension); return extHostNotebook.onDidChangeActiveNotebookKernel; diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index b004b04eb5f..0bf1bfa6493 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1623,6 +1623,7 @@ export interface ExtHostNotebookShape { $saveNotebookAs(viewType: string, uri: UriComponents, target: UriComponents, token: CancellationToken): Promise; $backup(viewType: string, uri: UriComponents, cancellation: CancellationToken): Promise; $acceptDisplayOrder(displayOrder: INotebookDisplayOrder): void; + $acceptNotebookActiveKernelChange(event: { uri: UriComponents, providerHandle: number | undefined, kernelId: string | undefined }): void; $renderOutputs(uriComponents: UriComponents, id: string, request: IOutputRenderRequest): Promise | undefined>; $renderOutputs2(uriComponents: UriComponents, id: string, request: IOutputRenderRequest): Promise | undefined>; $onDidReceiveMessage(editorId: string, rendererId: string | undefined, message: unknown): void; diff --git a/src/vs/workbench/api/common/extHostNotebook.ts b/src/vs/workbench/api/common/extHostNotebook.ts index c55f9218edc..515262f4cc4 100644 --- a/src/vs/workbench/api/common/extHostNotebook.ts +++ b/src/vs/workbench/api/common/extHostNotebook.ts @@ -767,11 +767,18 @@ export class ExtHostNotebookKernelProviderAdapter extends Disposable { const data = await this._provider.provideKernels(document, token) || []; const newMap = new Map(); + let kernel_unique_pool = 0; + let kernelIdCache = new Set(); const transformedData: INotebookKernelInfoDto2[] = data.map(kernel => { let id = this._kernelToId.get(kernel); if (id === undefined) { - id = UUID.generateUuid(); + if (kernel.id && kernelIdCache.has(kernel.id)) { + id = `${this._extension.identifier.value}_${kernel.id}_${kernel_unique_pool++}`; + } else { + id = `${this._extension.identifier.value}_${kernel.id || UUID.generateUuid()}`; + } + this._kernelToId.set(kernel, id); } @@ -798,6 +805,10 @@ export class ExtHostNotebookKernelProviderAdapter extends Disposable { return transformedData; } + getKernel(kernelId: string) { + return this._idToKernel.get(kernelId); + } + async resolveNotebook(kernelId: string, document: ExtHostNotebookDocument, webview: vscode.NotebookCommunication, token: CancellationToken) { const kernel = this._idToKernel.get(kernelId); @@ -864,9 +875,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN private _onDidCloseNotebookDocument = new Emitter(); onDidCloseNotebookDocument: Event = this._onDidCloseNotebookDocument.event; visibleNotebookEditors: ExtHostNotebookEditor[] = []; - activeNotebookKernel?: vscode.NotebookKernel; - - private _onDidChangeActiveNotebookKernel = new Emitter(); + private _onDidChangeActiveNotebookKernel = new Emitter<{ document: ExtHostNotebookDocument, kernel: vscode.NotebookKernel | undefined }>(); onDidChangeActiveNotebookKernel = this._onDidChangeActiveNotebookKernel.event; private _onDidChangeVisibleNotebookEditors = new Emitter(); onDidChangeVisibleNotebookEditors = this._onDidChangeVisibleNotebookEditors.event; @@ -1314,6 +1323,15 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN this._outputDisplayOrder = displayOrder; } + $acceptNotebookActiveKernelChange(event: { uri: UriComponents, providerHandle: number | undefined, kernelId: string | undefined }) { + if (event.providerHandle !== undefined) { + this._withAdapter(event.providerHandle, event.uri, async (adapter, document) => { + const kernel = event.kernelId ? adapter.getKernel(event.kernelId) : undefined; + this._onDidChangeActiveNotebookKernel.fire({ document, kernel }); + }); + } + } + // TODO: remove document - editor one on one mapping private _getEditorFromURI(uriComponents: UriComponents) { const uriStr = URI.revive(uriComponents).toString(); diff --git a/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts b/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts index c4db8ed24b9..41d059f556a 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookServiceImpl.ts @@ -174,6 +174,7 @@ export class NotebookService extends Disposable implements INotebookService, ICu private readonly _models = new Map(); private _onDidChangeActiveEditor = new Emitter(); onDidChangeActiveEditor: Event = this._onDidChangeActiveEditor.event; + private _activeEditorDisposables = new DisposableStore(); private _onDidChangeVisibleEditors = new Emitter(); onDidChangeVisibleEditors: Event = this._onDidChangeVisibleEditors.event; private readonly _onNotebookEditorAdd: Emitter = this._register(new Emitter()); @@ -191,6 +192,8 @@ export class NotebookService extends Disposable implements INotebookService, ICu private readonly _onDidChangeKernels = new Emitter(); onDidChangeKernels: Event = this._onDidChangeKernels.event; + private readonly _onDidChangeNotebookActiveKernel = new Emitter<{ uri: URI, providerHandle: number | undefined, kernelId: string | undefined }>(); + onDidChangeNotebookActiveKernel: Event<{ uri: URI, providerHandle: number | undefined, kernelId: string | undefined }> = this._onDidChangeNotebookActiveKernel.event; private cutItems: NotebookCellTextModel[] | undefined; private _lastClipboardIsCopy: boolean = true; @@ -768,6 +771,17 @@ export class NotebookService extends Disposable implements INotebookService, ICu } updateActiveNotebookEditor(editor: INotebookEditor | null) { + this._activeEditorDisposables.clear(); + + if (editor) { + this._activeEditorDisposables.add(editor.onDidChangeKernel(() => { + this._onDidChangeNotebookActiveKernel.fire({ + uri: editor.uri!, + providerHandle: editor.activeKernel?.providerHandle, + kernelId: editor.activeKernel?.id + }); + })); + } this._onDidChangeActiveEditor.fire(editor ? editor.getId() : null); } diff --git a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts index e7063754ffe..478bc1d959e 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookCommon.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookCommon.ts @@ -118,7 +118,9 @@ export interface INotebookKernelInfo { extension: ExtensionIdentifier; extensionLocation: URI, preloads: URI[]; + providerHandle?: number; executeNotebook(viewType: string, uri: URI, handle: number | undefined, token: CancellationToken): Promise; + } export interface INotebookKernelInfoDto { @@ -641,6 +643,7 @@ export interface INotebookKernelInfoDto2 { label: string; extension: ExtensionIdentifier; extensionLocation: URI; + providerHandle?: number; description?: string; isPreferred?: boolean; preloads?: UriComponents[]; diff --git a/src/vs/workbench/contrib/notebook/common/notebookService.ts b/src/vs/workbench/contrib/notebook/common/notebookService.ts index 4ca02503000..36f7d3192fa 100644 --- a/src/vs/workbench/contrib/notebook/common/notebookService.ts +++ b/src/vs/workbench/contrib/notebook/common/notebookService.ts @@ -43,6 +43,7 @@ export interface INotebookService { onNotebookDocumentRemove: Event; onNotebookDocumentAdd: Event; onDidChangeKernels: Event; + onDidChangeNotebookActiveKernel: Event<{ uri: URI, providerHandle: number | undefined, kernelId: string | undefined }>; registerNotebookController(viewType: string, extensionData: NotebookExtensionDescription, controller: IMainNotebookController): void; unregisterNotebookProvider(viewType: string): void; registerNotebookRenderer(id: string, renderer: INotebookRendererInfo): void;