Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion src/vs/workbench/api/browser/mainThreadNotebookKernels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/

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

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

private readonly _executions = new Map<number, INotebookCellExecution>();
Expand Down Expand Up @@ -309,4 +311,25 @@ export class MainThreadNotebookKernels implements MainThreadNotebookKernelsShape
this._kernelDetectionTasks.delete(handle);
}
}

// --- notebook kernel source action provider

async $addKernelSourceActionProvider(handle: number, notebookType: string): Promise<void> {
const kernelSourceActionProvider: IKernelSourceActionProvider = {
viewType: notebookType,
provideKernelSourceActions: async () => {
return this._proxy.$provideKernelSourceActions(handle, CancellationToken.None);
}
};
const registration = this._notebookKernelService.registerKernelSourceActionProvider(notebookType, kernelSourceActionProvider);
this._kernelSourceActionProviders.set(handle, [kernelSourceActionProvider, registration]);
}

$removeKernelSourceActionProvider(handle: number): void {
const tuple = this._kernelSourceActionProviders.get(handle);
if (tuple) {
tuple[1].dispose();
this._kernelSourceActionProviders.delete(handle);
}
}
}
5 changes: 5 additions & 0 deletions src/vs/workbench/api/common/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
checkProposedApiEnabled(extension, 'notebookKernelSource');
return extHostNotebookKernels.createNotebookControllerDetectionTask(extension, notebookType);
},
registerKernelSourceActionProvider(notebookType: string, provider: vscode.NotebookKernelSourceActionProvider) {
checkProposedApiEnabled(extension, 'notebookKernelSource');
return extHostNotebookKernels.registerKernelSourceActionProvider(extension, notebookType, provider);
},
onDidChangeNotebookCellExecutionState(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension, 'notebookCellExecutionState');
return extHostNotebookKernels.onDidChangeNotebookCellExecutionState(listener, thisArgs, disposables);
Expand Down Expand Up @@ -1345,6 +1349,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
NotebookControllerAffinity: extHostTypes.NotebookControllerAffinity,
NotebookControllerAffinity2: extHostTypes.NotebookControllerAffinity2,
NotebookEdit: extHostTypes.NotebookEdit,
NotebookKernelSourceAction: extHostTypes.NotebookKernelSourceAction,
PortAttributes: extHostTypes.PortAttributes,
LinkedEditingRanges: extHostTypes.LinkedEditingRanges,
TestResultState: extHostTypes.TestResultState,
Expand Down
4 changes: 4 additions & 0 deletions src/vs/workbench/api/common/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1045,6 +1045,9 @@ export interface MainThreadNotebookKernelsShape extends IDisposable {

$addKernelDetectionTask(handle: number, notebookType: string): Promise<void>;
$removeKernelDetectionTask(handle: number): void;

$addKernelSourceActionProvider(handle: number, notebookType: string): Promise<void>;
$removeKernelSourceActionProvider(handle: number): void;
}

export interface MainThreadNotebookRenderersShape extends IDisposable {
Expand Down Expand Up @@ -2134,6 +2137,7 @@ export interface ExtHostNotebookKernelsShape {
$cancelCells(handle: number, uri: UriComponents, handles: number[]): Promise<void>;
$acceptKernelMessageFromRenderer(handle: number, editorId: string, message: any): void;
$cellExecutionChanged(uri: UriComponents, cellHandle: number, state: notebookCommon.NotebookCellExecutionState | undefined): void;
$provideKernelSourceActions(handle: number, token: CancellationToken): Promise<notebookCommon.INotebookKernelSourceAction[]>;
}

export interface ExtHostInteractiveShape {
Expand Down
38 changes: 35 additions & 3 deletions src/vs/workbench/api/common/extHostNotebookKernels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

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

private _kernelSourceActionProviders = new Map<number, vscode.NotebookKernelSourceActionProvider>();
private _kernelSourceActionProviderHandlePool: number = 0;
private _kernelSourceActionProviderCache = new Cache<IDisposable>('NotebookKernelSourceActionProviderCache');

private readonly _kernelData = new Map<number, IKernelData>();
private _handlePool: number = 0;

Expand Down Expand Up @@ -292,6 +297,33 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
return detectionTask;
}

registerKernelSourceActionProvider(extension: IExtensionDescription, viewType: string, provider: vscode.NotebookKernelSourceActionProvider) {
const handle = this._kernelSourceActionProviderHandlePool++;
const that = this;

this._kernelSourceActionProviders.set(handle, provider);
this._logService.trace(`NotebookKernelSourceActionProvider[${handle}], CREATED by ${extension.identifier.value}`);
this._proxy.$addKernelSourceActionProvider(handle, viewType);

return {
dispose: () => {
this._kernelSourceActionProviders.delete(handle);
that._proxy.$removeKernelSourceActionProvider(handle);
}
};
}

async $provideKernelSourceActions(handle: number, token: CancellationToken): Promise<INotebookKernelSourceAction[]> {
const provider = this._kernelSourceActionProviders.get(handle);
if (provider) {
const disposables = new DisposableStore();
this._kernelSourceActionProviderCache.add([disposables]);
const ret = await provider.provideNotebookKernelSourceActions(token);
return (ret ?? []).map(item => extHostTypeConverters.NotebookKernelSourceAction.from(item, this._commands.converter, disposables));
}
return [];
}

$acceptNotebookAssociation(handle: number, uri: UriComponents, value: boolean): void {
const obj = this._kernelData.get(handle);
if (obj) {
Expand Down
13 changes: 13 additions & 0 deletions src/vs/workbench/api/common/extHostTypeConverters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1705,6 +1705,19 @@ export namespace NotebookStatusBarItem {
}
}

export namespace NotebookKernelSourceAction {
export function from(item: vscode.NotebookKernelSourceAction, commandsConverter: Command.ICommandsConverter, disposables: DisposableStore): notebooks.INotebookKernelSourceAction {
const command = typeof item.command === 'string' ? { title: '', command: item.command } : item.command;

return {
command: commandsConverter.toInternal(command, disposables),
label: item.label,
description: item.description,
detail: item.detail
};
}
}

export namespace NotebookDocumentContentOptions {
export function from(options: vscode.NotebookDocumentContentOptions | undefined): notebooks.TransientOptions {
return {
Expand Down
9 changes: 9 additions & 0 deletions src/vs/workbench/api/common/extHostTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3617,6 +3617,15 @@ export class NotebookRendererScript {
}
}

export class NotebookKernelSourceAction {
description?: string;
detail?: string;
command?: vscode.Command;
constructor(
public label: string
) { }
}

//#endregion

//#region Timeline
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

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

readonly onDidChangeSelectedNotebooks: Event<ISelectedNotebooksChangeEvent> = this._onDidChangeNotebookKernelBinding.event;
readonly onDidAddKernel: Event<INotebookKernel> = this._onDidAddKernel.event;
Expand Down Expand Up @@ -366,4 +367,31 @@ export class NotebookKernelService extends Disposable implements INotebookKernel
getKernelDetectionTasks(notebook: INotebookTextModelLike): INotebookKernelDetectionTask[] {
return this._kernelDetectionTasks.get(notebook.viewType) ?? [];
}

registerKernelSourceActionProvider(viewType: string, provider: IKernelSourceActionProvider): IDisposable {
const providers = this._kernelSourceActionProviders.get(viewType) ?? [];
providers.push(provider);
this._kernelSourceActionProviders.set(viewType, providers);

return toDisposable(() => {
const providers = this._kernelSourceActionProviders.get(viewType) ?? [];
const idx = providers.indexOf(provider);
if (idx >= 0) {
providers.splice(idx, 1);
this._kernelSourceActionProviders.set(viewType, providers);
}
});
}

/**
* Get kernel source actions from providers
*/
getKernelSourceActions2(notebook: INotebookTextModelLike): Promise<INotebookKernelSourceAction[]> {
const viewType = notebook.viewType;
const providers = this._kernelSourceActionProviders.get(viewType) ?? [];
const promises = providers.map(provider => provider.provideKernelSourceActions());
return Promise.all(promises).then(actions => {
return actions.reduce((a, b) => a.concat(b), []);
});
}
}
Loading