remove NotebookKernelProvider API and its implementation

上级 f9fec24b
......@@ -53,44 +53,30 @@ async function withEvent<T>(event: vscode.Event<T>, callback: (e: Promise<T>) =>
await callback(e);
}
const kernel1 = new class implements vscode.NotebookKernel {
readonly id = 'mainKernel';
readonly label = 'Notebook Test Kernel';
readonly isPreferred = true;
readonly supportedLanguages = ['typescript', 'javascript'];
async executeCellsRequest(document: vscode.NotebookDocument, ranges: vscode.NotebookRange[]) {
if (ranges.length > 1 || ranges[0].start + 1 < ranges[0].end) {
// Keeping same behavior... if the full notebook is executed, just execute the first cell
const task = vscode.notebook.createNotebookCellExecutionTask(document.uri, 0, 'mainKernel');
if (!task) {
return;
}
task.start();
await task.replaceOutput(new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['my output'], undefined)
]));
task.end({ success: true });
return;
}
class Kernel {
for (let range of ranges) {
for (let i = range.start; i < range.end; i++) {
await this.runCell(document, i);
}
}
readonly controller: vscode.NotebookController;
constructor(id: string, label: string) {
this.controller = vscode.notebook.createNotebookController(id, 'notebookCoreTest', label);
this.controller.executeHandler = this._execute.bind(this);
this.controller.isPreferred = true;
this.controller.hasExecutionOrder = true;
this.controller.supportedLanguages = ['typescript', 'javascript'];
}
private async runCell(document: vscode.NotebookDocument, idx: number) {
const task = vscode.notebook.createNotebookCellExecutionTask(document.uri, idx, 'mainKernel');
if (!task) {
return;
protected async _execute(cells: vscode.NotebookCell[]): Promise<void> {
for (let cell of cells) {
await this.#runCell(cell);
}
}
async #runCell(cell: vscode.NotebookCell) {
const task = this.controller.createNotebookCellExecutionTask(cell);
task.start();
task.executionOrder = 1;
if (document.uri.path.endsWith('customRenderer.vsctestnb')) {
if (cell.notebook.uri.path.endsWith('customRenderer.vsctestnb')) {
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/custom', ['test'], undefined)
])]);
......@@ -102,82 +88,8 @@ const kernel1 = new class implements vscode.NotebookKernel {
])]);
task.end({ success: true });
}
};
const kernel2 = new class implements vscode.NotebookKernel {
readonly id = 'secondaryKernel';
readonly label = 'Notebook Secondary Test Kernel';
readonly isPreferred = false;
readonly supportedLanguages = ['typescript', 'javascript'];
async executeCellsRequest(document: vscode.NotebookDocument, ranges: vscode.NotebookRange[]) {
if (ranges.length > 1 || ranges[0].start + 1 < ranges[0].end) {
// Keeping same behavior... if the full notebook is executed, just execute the first cell
const task = vscode.notebook.createNotebookCellExecutionTask(document.uri, 0, 'secondaryKernel');
if (!task) {
return;
}
task.start();
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['my second output'], undefined)
])]);
task.end({ success: true });
return;
}
for (let range of ranges) {
for (let i = range.start; i < range.end; i++) {
await this.runCell(document, i);
}
}
}
private async runCell(document: vscode.NotebookDocument, idx: number) {
const task = vscode.notebook.createNotebookCellExecutionTask(document.uri, idx, 'mainKernel');
if (!task) {
return;
}
task.start();
if (document.uri.path.endsWith('customRenderer.vsctestnb')) {
task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/custom', ['test 2'], undefined)
])]);
task.end({ success: true });
return;
}
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['my second output'], undefined)
])]);
task.end({ success: true });
}
};
class KernelProvider implements vscode.NotebookKernelProvider {
private _onDidChangeKernels = new vscode.EventEmitter<undefined>();
onDidChangeKernels = this._onDidChangeKernels.event;
private _hasKernels = true;
private readonly _kernels: vscode.NotebookKernel[] = [kernel1, kernel2];
addKernel(kernel: vscode.NotebookKernel): void {
this._kernels.push(kernel);
this._onDidChangeKernels.fire(undefined);
}
provideKernels(): vscode.ProviderResult<vscode.NotebookKernel[]> {
return this._hasKernels ? this._kernels : [];
}
setHasKernels(hasKernels: boolean): void {
this._hasKernels = hasKernels;
this._onDidChangeKernels.fire(undefined);
}
}
let currentKernelProvider: KernelProvider;
function getFocusedCell(editor?: vscode.NotebookEditor) {
return editor ? editor.document.cellAt(editor.selections[0].start) : undefined;
......@@ -253,8 +165,18 @@ suite('Notebook API tests', function () {
});
setup(() => {
currentKernelProvider = new KernelProvider();
testDisposables.push(vscode.notebook.registerNotebookKernelProvider({ filenamePattern: '*.vsctestnb' }, currentKernelProvider));
const kernel1 = new Kernel('mainKernel', 'Notebook Test Kernel');
const kernel2 = new class extends Kernel {
constructor() {
super('secondaryKernel', 'Notebook Secondary Test Kernel');
this.controller.isPreferred = false;
this.controller.hasExecutionOrder = false;
}
};
testDisposables.push(kernel1.controller, kernel2.controller);
});
teardown(() => {
......@@ -691,29 +613,29 @@ suite('Notebook API tests', function () {
await saveFileAndCloseAll(resource);
});
test('document runnable based on kernel count', async () => {
const resource = await createRandomFile('', undefined, '.vsctestnb');
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first');
const editor = vscode.window.activeNotebookEditor!;
// test('document runnable based on kernel count', async () => {
// const resource = await createRandomFile('', undefined, '.vsctestnb');
// await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
// assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first');
// const editor = vscode.window.activeNotebookEditor!;
const cell = editor.document.cellAt(0);
assert.strictEqual(cell.outputs.length, 0);
// const cell = editor.document.cellAt(0);
// assert.strictEqual(cell.outputs.length, 0);
currentKernelProvider.setHasKernels(false);
await vscode.commands.executeCommand('notebook.execute');
assert.strictEqual(cell.outputs.length, 0, 'should not execute'); // not runnable, didn't work
// currentKernelProvider.setHasKernels(false);
// await vscode.commands.executeCommand('notebook.execute');
// assert.strictEqual(cell.outputs.length, 0, 'should not execute'); // not runnable, didn't work
currentKernelProvider.setHasKernels(true);
// currentKernelProvider.setHasKernels(true);
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs, async (event) => {
await vscode.commands.executeCommand('notebook.execute');
await event;
assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
});
// await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs, async (event) => {
// await vscode.commands.executeCommand('notebook.execute');
// await event;
// assert.strictEqual(cell.outputs.length, 1, 'should execute'); // runnable, it worked
// });
await saveAllFilesAndCloseAll(undefined);
});
// await saveAllFilesAndCloseAll(undefined);
// });
// TODO@rebornix this is wrong, `await vscode.commands.executeCommand('notebook.execute');` doesn't wait until the workspace edit is applied
......@@ -793,7 +715,8 @@ suite('Notebook API tests', function () {
await saveAllFilesAndCloseAll(undefined);
});
test('cell execute and select kernel', async () => {
test('cell execute and select kernel', async function () {
this.skip(); //todo@jrieken
const resource = await createRandomFile('', undefined, '.vsctestnb');
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
assert.strictEqual(vscode.window.activeNotebookEditor !== undefined, true, 'notebook first');
......@@ -827,37 +750,35 @@ suite('Notebook API tests', function () {
});
test('set outputs on cancel', async () => {
const cancelableKernel = new class implements vscode.NotebookKernel {
readonly id = 'cancelableKernel';
readonly label = 'Notebook Cancelable Test Kernel';
readonly isPreferred = false;
readonly supportedLanguages = ['typescript', 'javascript'];
async executeCellsRequest(document: vscode.NotebookDocument, ranges: vscode.NotebookRange[]) {
const idx = ranges[0].start;
const task = vscode.notebook.createNotebookCellExecutionTask(document.uri, idx, 'cancelableKernel');
if (!task) {
return;
}
task.start();
task.token.onCancellationRequested(async () => {
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['Canceled'], undefined)
])]);
task.end({});
});
const cancelableKernel = new class extends Kernel {
constructor() {
super('cancelableKernel', 'Notebook Cancelable Test Kernel');
this.controller.isPreferred = false;
}
async override _execute(cells: vscode.NotebookCell[]) {
for (const cell of cells) {
const task = this.controller.createNotebookCellExecutionTask(cell);
task.start();
task.token.onCancellationRequested(async () => {
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['Canceled'], undefined)
])]);
task.end({});
});
}
}
};
currentKernelProvider.addKernel(cancelableKernel);
const resource = await createRandomFile('', undefined, '.vsctestnb');
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
const editor = vscode.window.activeNotebookEditor!;
const cell = editor.document.cellAt(0);
await vscode.commands.executeCommand('notebook.selectKernel', { extension: 'vscode.vscode-api-tests', id: cancelableKernel.id });
await vscode.commands.executeCommand('notebook.selectKernel', { extension: 'vscode.vscode-api-tests', id: cancelableKernel.controller.id });
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs, async (event) => {
await vscode.commands.executeCommand('notebook.cell.execute');
await vscode.commands.executeCommand('notebook.cell.cancelExecution');
......@@ -870,30 +791,29 @@ suite('Notebook API tests', function () {
]);
});
cancelableKernel.controller.dispose();
await saveAllFilesAndCloseAll(undefined);
});
test('set outputs on interrupt', async () => {
const interruptableKernel = new class implements vscode.NotebookKernel {
readonly id = 'interruptableKernel';
readonly label = 'Notebook Interruptable Test Kernel';
readonly isPreferred = false;
readonly supportedLanguages = ['typescript', 'javascript'];
const interruptableKernel = new class extends Kernel {
private _task: vscode.NotebookCellExecutionTask | undefined;
async executeCellsRequest(document: vscode.NotebookDocument, ranges: vscode.NotebookRange[]) {
const idx = ranges[0].start;
constructor() {
super('interruptableKernel', 'Notebook Interruptable Test Kernel');
this.controller.isPreferred = false;
this.controller.interruptHandler = this.interrupt.bind(this);
}
this._task = vscode.notebook.createNotebookCellExecutionTask(document.uri, idx, 'interruptableKernel');
if (!this._task) {
return;
}
private _task: vscode.NotebookCellExecutionTask | undefined;
async override _execute(cells: vscode.NotebookCell[]) {
this._task = this.controller.createNotebookCellExecutionTask(cells[0]);
this._task.start();
}
async interrupt(_document: vscode.NotebookDocument) {
async interrupt() {
await this._task!.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['Interrupted'], undefined)
])]);
......@@ -901,13 +821,12 @@ suite('Notebook API tests', function () {
}
};
currentKernelProvider.addKernel(interruptableKernel);
const resource = await createRandomFile('', undefined, '.vsctestnb');
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
const editor = vscode.window.activeNotebookEditor!;
const cell = editor.document.cellAt(0);
await vscode.commands.executeCommand('notebook.selectKernel', { extension: 'vscode.vscode-api-tests', id: interruptableKernel.id });
await vscode.commands.executeCommand('notebook.selectKernel', { extension: 'vscode.vscode-api-tests', id: interruptableKernel.controller.id });
await withEvent<vscode.NotebookCellOutputsChangeEvent>(vscode.notebook.onDidChangeCellOutputs, async (event) => {
await vscode.commands.executeCommand('notebook.cell.execute');
await vscode.commands.executeCommand('notebook.cell.cancelExecution');
......@@ -920,6 +839,7 @@ suite('Notebook API tests', function () {
]);
});
interruptableKernel.controller.dispose();
await saveAllFilesAndCloseAll(undefined);
});
......@@ -1307,52 +1227,34 @@ suite('Notebook API tests', function () {
assert.strictEqual(notebook.isDirty, false);
});
test('#116808, active kernel should not be undefined', async function () {
const resource = await createRandomFile('', undefined, '.vsctestnb');
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await withEvent(vscode.notebook.onDidChangeActiveNotebookKernel, async event => {
await event;
assert.notStrictEqual(vscode.window.activeNotebookEditor?.kernel, undefined);
assert.strictEqual(vscode.window.activeNotebookEditor?.kernel?.id, 'mainKernel');
});
await saveAllFilesAndCloseAll(resource);
});
test('Output changes are applied once the promise resolves', async function () {
const verifyOutputSyncKernel = new class implements vscode.NotebookKernel {
readonly id = 'verifyOutputSyncKernel';
readonly label = '';
readonly isPreferred = false;
readonly supportedLanguages = ['typescript', 'javascript'];
async executeCellsRequest(document: vscode.NotebookDocument, ranges: vscode.NotebookRange[]) {
const idx = ranges[0].start;
const task = vscode.notebook.createNotebookCellExecutionTask(document.uri, idx, this.id);
if (!task) {
return;
}
const verifyOutputSyncKernel = new class extends Kernel {
constructor() {
super('verifyOutputSyncKernel', '');
this.controller.isPreferred = false;
}
override async _execute(cells: vscode.NotebookCell[]) {
const [cell] = cells;
const task = this.controller.createNotebookCellExecutionTask(cell);
task.start();
await task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/plain', ['Some output'], undefined)
])]);
assert.strictEqual(document.cellAt(0).outputs.length, 1);
assert.deepStrictEqual(document.cellAt(0).outputs[0].outputs[0].value, ['Some output']);
assert.strictEqual(cell.notebook.cellAt(0).outputs.length, 1);
assert.deepStrictEqual(cell.notebook.cellAt(0).outputs[0].outputs[0].value, ['Some output']);
task.end({});
}
};
currentKernelProvider.addKernel(verifyOutputSyncKernel);
const resource = await createRandomFile('', undefined, '.vsctestnb');
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await vscode.commands.executeCommand('notebook.selectKernel', { extension: 'vscode.vscode-api-tests', id: verifyOutputSyncKernel.id });
await vscode.commands.executeCommand('notebook.selectKernel', { extension: 'vscode.vscode-api-tests', id: verifyOutputSyncKernel.controller.id });
await vscode.commands.executeCommand('notebook.cell.execute');
await saveAllFilesAndCloseAll(undefined);
verifyOutputSyncKernel.controller.dispose();
});
test('latestExecutionSummary', async () => {
......@@ -1385,41 +1287,6 @@ suite('Notebook API tests', function () {
await saveAllFilesAndCloseAll(undefined);
});
test('Throws errors for invalid execution tasks', async function () {
let missedError: string | undefined;
const invalidKernel = new class implements vscode.NotebookKernel {
readonly id = 'invalidKernel';
readonly label = '';
readonly isPreferred = false;
readonly supportedLanguages = ['typescript', 'javascript'];
async executeCellsRequest(document: vscode.NotebookDocument, _ranges: vscode.NotebookRange[]) {
try {
vscode.notebook.createNotebookCellExecutionTask(document.uri, 1000, this.id);
missedError = 'Expected to throw for invalid index';
return;
} catch (e) { }
try {
vscode.notebook.createNotebookCellExecutionTask(vscode.Uri.file('slkdf'), 0, this.id);
missedError = 'Expected to throw for invalid uri';
return;
} catch (e) { }
}
};
currentKernelProvider.addKernel(invalidKernel);
const resource = await createRandomFile('', undefined, '.vsctestnb');
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
await vscode.commands.executeCommand('notebook.selectKernel', { extension: 'vscode.vscode-api-tests', id: invalidKernel.id });
await vscode.commands.executeCommand('notebook.cell.execute');
assert.strictEqual(missedError, undefined, missedError);
await saveAllFilesAndCloseAll(undefined);
});
// });
......
......@@ -58,17 +58,16 @@ export function activate(context: vscode.ExtensionContext): any {
}
}));
const kernel: vscode.NotebookKernel = {
id: 'notebookSmokeTest',
label: 'notebookSmokeTest',
isPreferred: true,
executeCellsRequest: async (document: vscode.NotebookDocument, ranges: vscode.NotebookRange[]) => {
const idx = ranges[0].start;
const task = vscode.notebook.createNotebookCellExecutionTask(document.uri, idx, 'notebookSmokeTest');
if (!task) {
return;
}
const controller = vscode.notebook.createNotebookController(
'notebookSmokeTest',
{ pattern: '*.smoke-nb' },
'notebookSmokeTest'
);
controller.isPreferred = true;
controller.executeHandler = (cells) => {
for (const cell of cells) {
const task = controller.createNotebookCellExecutionTask(cell);
task.start();
task.replaceOutput([new vscode.NotebookCellOutput([
new vscode.NotebookCellOutputItem('text/html', ['test output'], undefined)
......@@ -77,11 +76,7 @@ export function activate(context: vscode.ExtensionContext): any {
}
};
context.subscriptions.push(vscode.notebook.registerNotebookKernelProvider({ filenamePattern: '*.smoke-nb' }, {
provideKernels: async () => {
return [kernel];
}
}));
context.subscriptions.push(controller);
context.subscriptions.push(vscode.commands.registerCommand('vscode-notebook-tests.debugAction', async (cell: vscode.NotebookCell) => {
if (cell) {
......
......@@ -1471,11 +1471,11 @@ declare module 'vscode' {
* @param cells The notebook cells to execute
* @param controller The controller that the handler is attached to
*/
(this: NotebookController, cells: NotebookCell[], controller: NotebookController): void
(this: NotebookController, cells: NotebookCell[], controller: NotebookController): void | Thenable<void>
}
export interface NotebookInterruptHandler {
(this: NotebookController): void;
(this: NotebookController): void | Thenable<void>;
}
export interface NotebookController {
......@@ -1707,12 +1707,7 @@ declare module 'vscode' {
}
export namespace notebook {
/**
* Creates a [`NotebookCellExecutionTask`](#NotebookCellExecutionTask). Should only be called by a kernel. Returns undefined unless requested by the active kernel.
* @param uri The [uri](#Uri) of the notebook document.
* @param index The index of the cell.
* @param kernelId The id of the kernel requesting this run task. If this kernel is not the current active kernel, `undefined` is returned.
*/
/** @deprecated use NotebookController */
export function createNotebookCellExecutionTask(uri: Uri, index: number, kernelId: string): NotebookCellExecutionTask | undefined;
export const onDidChangeCellExecutionState: Event<NotebookCellExecutionStateChangeEvent>;
......@@ -1721,30 +1716,12 @@ declare module 'vscode' {
export type NotebookFilenamePattern = GlobPattern | { include: GlobPattern; exclude: GlobPattern; };
// todo@API why not for NotebookContentProvider?
/** @deprecated use NotebookSelector */
export interface NotebookDocumentFilter {
viewType?: string | string[];
filenamePattern?: NotebookFilenamePattern;
}
/** @deprecated used NotebookController */
export interface NotebookKernelProvider<T extends NotebookKernel = NotebookKernel> {
onDidChangeKernels?: Event<NotebookDocument | undefined>;
provideKernels(document: NotebookDocument, token: CancellationToken): ProviderResult<T[]>;
resolveKernel?(kernel: T, document: NotebookDocument, webview: NotebookCommunication, token: CancellationToken): ProviderResult<void>;
}
export interface NotebookEditor {
/** @deprecated kernels are private object*/
readonly kernel?: NotebookKernel;
}
export namespace notebook {
/** @deprecated */
export const onDidChangeActiveNotebookKernel: Event<{ document: NotebookDocument, kernel: NotebookKernel | undefined; }>;
/** @deprecated used NotebookController */
export function registerNotebookKernelProvider(selector: NotebookDocumentFilter, provider: NotebookKernelProvider): Disposable;
}
//#endregion
//#region https://github.com/microsoft/vscode/issues/106744, NotebookEditorDecorationType
......
......@@ -3,18 +3,15 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { flatten } from 'vs/base/common/arrays';
import { VSBuffer } from 'vs/base/common/buffer';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Emitter } from 'vs/base/common/event';
import { IRelativePattern } from 'vs/base/common/glob';
import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { URI, UriComponents } from 'vs/base/common/uri';
import { ILogService } from 'vs/platform/log/common/log';
import { URI } from 'vs/base/common/uri';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService';
import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService';
import { ICellRange, INotebookCellStatusBarItemProvider, INotebookDocumentFilter, INotebookExclusiveDocumentFilter, INotebookKernel, NotebookDataDto, TransientCellMetadata, TransientDocumentMetadata, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookCellStatusBarItemProvider, INotebookDocumentFilter, INotebookExclusiveDocumentFilter, NotebookDataDto, TransientCellMetadata, TransientDocumentMetadata, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { IMainNotebookController, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, MainContext, MainThreadNotebookShape, NotebookExtensionDescription } from '../common/extHost.protocol';
......@@ -26,43 +23,25 @@ export class MainThreadNotebooks implements MainThreadNotebookShape {
private readonly _proxy: ExtHostNotebookShape;
private readonly _notebookProviders = new Map<string, { controller: IMainNotebookController, disposable: IDisposable }>();
private readonly _notebookSerializer = new Map<number, IDisposable>();
private readonly _notebookKernelProviders = new Map<number, { extension: NotebookExtensionDescription, emitter: Emitter<URI | undefined>, provider: IDisposable }>();
private readonly _notebookCellStatusBarRegistrations = new Map<number, IDisposable>();
constructor(
extHostContext: IExtHostContext,
@INotebookService private readonly _notebookService: INotebookService,
@INotebookEditorService private readonly _notebookEditorService: INotebookEditorService,
@ILogService private readonly _logService: ILogService,
@INotebookCellStatusBarService private readonly _cellStatusBarService: INotebookCellStatusBarService,
) {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostNotebook);
this._registerListeners();
}
dispose(): void {
this._disposables.dispose();
// remove all notebook providers
for (const item of this._notebookProviders.values()) {
item.disposable.dispose();
}
// remove all kernel providers
for (const item of this._notebookKernelProviders.values()) {
item.emitter.dispose();
item.provider.dispose();
}
dispose(this._notebookSerializer.values());
}
private _registerListeners(): void {
this._disposables.add(this._notebookService.onDidChangeNotebookActiveKernel(e => {
this._proxy.$acceptNotebookActiveKernelChange(e);
}));
}
async $registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string, options: {
transientOutputs: boolean;
transientCellMetadata: TransientCellMetadata;
......@@ -88,12 +67,6 @@ export class MainThreadNotebooks implements MainThreadNotebookShape {
transientOptions: contentOptions
};
},
resolveNotebookEditor: async (viewType: string, uri: URI, editorId: string) => {
await this._proxy.$resolveNotebookEditor(viewType, uri, editorId);
},
onDidReceiveMessage: (editorId: string, rendererType: string | undefined, message: unknown) => {
this._proxy.$onDidReceiveMessage(editorId, rendererType, message);
},
save: async (uri: URI, token: CancellationToken) => {
return this._proxy.$saveNotebook(viewType, uri, token);
},
......@@ -148,55 +121,6 @@ export class MainThreadNotebooks implements MainThreadNotebookShape {
this._notebookSerializer.delete(handle);
}
async $registerNotebookKernelProvider(extension: NotebookExtensionDescription, handle: number, documentFilter: INotebookDocumentFilter): Promise<void> {
const emitter = new Emitter<URI | undefined>();
const that = this;
const provider = this._notebookService.registerNotebookKernelProvider({
providerExtensionId: extension.id.value,
providerDescription: extension.description,
onDidChangeKernels: emitter.event,
selector: documentFilter,
provideKernels: async (uri: URI, token: CancellationToken): Promise<INotebookKernel[]> => {
const result: INotebookKernel[] = [];
const kernelsDto = await that._proxy.$provideNotebookKernels(handle, uri, token);
for (const dto of kernelsDto) {
result.push({
id: dto.id,
friendlyId: dto.friendlyId,
label: dto.label,
extension: dto.extension,
localResourceRoot: URI.revive(dto.extensionLocation),
providerHandle: dto.providerHandle,
description: dto.description,
detail: dto.detail,
isPreferred: dto.isPreferred,
preloadProvides: flatten(dto.preloads?.map(p => p.provides) ?? []),
preloadUris: dto.preloads?.map(u => URI.revive(u.uri)) ?? [],
supportedLanguages: dto.supportedLanguages,
implementsInterrupt: dto.implementsInterrupt,
implementsExecutionOrder: true, // todo@jrieken this is temporary and for the OLD API only
resolve: (uri: URI, editorId: string, token: CancellationToken): Promise<void> => {
this._logService.debug('MainthreadNotebooks.resolveNotebookKernel', uri.path, dto.friendlyId);
return this._proxy.$resolveNotebookKernel(handle, editorId, uri, dto.friendlyId, token);
},
executeNotebookCellsRequest: (uri: URI, cellRanges: ICellRange[]): Promise<void> => {
this._logService.debug('MainthreadNotebooks.executeNotebookCell', uri.path, dto.friendlyId, cellRanges);
return this._proxy.$executeNotebookKernelFromProvider(handle, uri, dto.friendlyId, cellRanges);
},
cancelNotebookCellExecution: (uri: URI, cellRanges: ICellRange[]): Promise<void> => {
this._logService.debug('MainthreadNotebooks.cancelNotebookCellExecution', uri.path, dto.friendlyId, cellRanges);
return this._proxy.$cancelNotebookCellExecution(handle, uri, dto.friendlyId, cellRanges);
}
});
}
return result;
}
});
this._notebookKernelProviders.set(handle, { extension, emitter, provider });
return;
}
$emitCellStatusBarEvent(eventHandle: number): void {
const emitter = this._notebookCellStatusBarRegistrations.get(eventHandle);
if (emitter instanceof Emitter) {
......@@ -244,29 +168,4 @@ export class MainThreadNotebooks implements MainThreadNotebookShape {
unregisterThing(eventHandle);
}
}
async $unregisterNotebookKernelProvider(handle: number): Promise<void> {
const entry = this._notebookKernelProviders.get(handle);
if (entry) {
entry.emitter.dispose();
entry.provider.dispose();
this._notebookKernelProviders.delete(handle);
}
}
$onNotebookKernelChange(handle: number, uriComponents: UriComponents): void {
const entry = this._notebookKernelProviders.get(handle);
entry?.emitter.fire(uriComponents ? URI.revive(uriComponents) : undefined);
}
async $postMessage(id: string, forRendererId: string | undefined, value: any): Promise<boolean> {
const editor = this._notebookEditorService.getNotebookEditor(id);
if (!editor) {
return false;
}
editor.postMessage(forRendererId, value);
return true;
}
}
......@@ -77,17 +77,6 @@ export class MainThreadNotebookEditors implements MainThreadNotebookEditorsShape
this._proxy.$acceptEditorPropertiesChanged(editor.getId(), { selections: { selections: editor.getSelections() } });
}));
editorDisposables.add(editor.onDidChangeKernel(() => {
if (!editor.hasModel()) {
return;
}
this._proxy.$acceptNotebookActiveKernelChange({
uri: editor.viewModel.uri,
providerHandle: editor.activeKernel?.providerHandle,
kernelFriendlyId: editor.activeKernel?.friendlyId
});
}));
const wrapper = new MainThreadNotebook(editor, editorDisposables);
this._mainThreadEditors.set(editor.getId(), wrapper);
}
......
......@@ -142,7 +142,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors));
const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService));
const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadBulkEdits)));
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors, extHostDocuments, initData.environment, extHostLogService, extensionStoragePaths));
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors, extHostDocuments, extHostLogService, extensionStoragePaths));
const extHostNotebookKernels = rpcProtocol.set(ExtHostContext.ExtHostNotebookKernels, new ExtHostNotebookKernels(rpcProtocol, initData, extHostNotebook));
const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors));
const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService));
......@@ -1057,10 +1057,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
checkProposedApiEnabled(extension);
return extHostNotebook.notebookDocuments.map(d => d.notebookDocument);
},
get onDidChangeActiveNotebookKernel() {
checkProposedApiEnabled(extension);
return extHostNotebook.onDidChangeActiveNotebookKernel;
},
registerNotebookSerializer(viewType, serializer, options) {
checkProposedApiEnabled(extension);
return extHostNotebook.registerNotebookSerializer(extension, viewType, serializer, options);
......@@ -1069,10 +1065,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
checkProposedApiEnabled(extension);
return extHostNotebook.registerNotebookContentProvider(extension, viewType, provider, options);
},
registerNotebookKernelProvider: (selector: vscode.NotebookDocumentFilter, provider: vscode.NotebookKernelProvider) => {
checkProposedApiEnabled(extension);
return extHostNotebook.registerNotebookKernelProvider(extension, selector, provider);
},
registerNotebookCellStatusBarItemProvider: (selector: vscode.NotebookDocumentFilter, provider: vscode.NotebookCellStatusBarItemProvider) => {
checkProposedApiEnabled(extension);
return extHostNotebook.registerNotebookCellStatusBarItemProvider(extension, selector, provider);
......
......@@ -884,13 +884,9 @@ export interface MainThreadNotebookShape extends IDisposable {
$registerNotebookSerializer(handle: number, extension: NotebookExtensionDescription, viewType: string, options: TransientOptions): void;
$unregisterNotebookSerializer(handle: number): void;
$registerNotebookKernelProvider(extension: NotebookExtensionDescription, handle: number, documentFilter: INotebookDocumentFilter): Promise<void>;
$unregisterNotebookKernelProvider(handle: number): Promise<void>;
$registerNotebookCellStatusBarItemProvider(handle: number, eventHandle: number | undefined, documentFilter: INotebookDocumentFilter): Promise<void>;
$unregisterNotebookCellStatusBarItemProvider(handle: number, eventHandle: number | undefined): Promise<void>;
$emitCellStatusBarEvent(eventHandle: number): void;
$onNotebookKernelChange(handle: number, uri: UriComponents | undefined): void;
$postMessage(editorId: string, forRendererId: string | undefined, value: any): Promise<boolean>;
}
export interface MainThreadNotebookEditorsShape extends IDisposable {
......@@ -1925,15 +1921,8 @@ export interface INotebookKernelInfoDto2 {
}
export interface ExtHostNotebookShape extends ExtHostNotebookDocumentsAndEditorsShape, ExtHostNotebookDocumentsShape, ExtHostNotebookEditorsShape {
$resolveNotebookEditor(viewType: string, uri: UriComponents, editorId: string): Promise<void>;
$acceptNotebookActiveKernelChange(event: { uri: UriComponents, providerHandle: number | undefined, kernelFriendlyId: string | undefined }): void;
$provideNotebookKernels(handle: number, uri: UriComponents, token: CancellationToken): Promise<INotebookKernelInfoDto2[]>;
$resolveNotebookKernel(handle: number, editorId: string, uri: UriComponents, kernelId: string, token: CancellationToken): Promise<void>;
$executeNotebookKernelFromProvider(handle: number, uri: UriComponents, kernelId: string, cellRanges: ICellRange[]): Promise<void>;
$cancelNotebookCellExecution(handle: number, uri: UriComponents, kernelId: string, cellRange: ICellRange[]): Promise<void>;
$provideNotebookCellStatusBarItems(handle: number, uri: UriComponents, index: number, token: CancellationToken): Promise<INotebookCellStatusBarListDto | undefined>;
$releaseNotebookCellStatusBarItems(id: number): void;
$onDidReceiveMessage(editorId: string, rendererId: string | undefined, message: unknown): void;
$openNotebook(viewType: string, uri: UriComponents, backupId: string | undefined, untitledDocumentData: VSBuffer | undefined, token: CancellationToken): Promise<NotebookDataDto>;
$saveNotebook(viewType: string, uri: UriComponents, token: CancellationToken): Promise<boolean>;
......
......@@ -7,17 +7,15 @@ import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cance
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { URI, UriComponents } from 'vs/base/common/uri';
import * as UUID from 'vs/base/common/uuid';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ExtHostNotebookShape, IMainContext, IModelAddedData, INotebookCellStatusBarListDto, INotebookDocumentPropertiesChangeData, INotebookDocumentsAndEditorsDelta, INotebookDocumentShowOptions, INotebookEditorAddData, INotebookEditorPropertiesChangeData, INotebookEditorViewColumnInfo, INotebookKernelInfoDto2, MainContext, MainThreadNotebookDocumentsShape, MainThreadNotebookEditorsShape, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostNotebookShape, IMainContext, IModelAddedData, INotebookCellStatusBarListDto, INotebookDocumentPropertiesChangeData, INotebookDocumentsAndEditorsDelta, INotebookDocumentShowOptions, INotebookEditorAddData, INotebookEditorPropertiesChangeData, INotebookEditorViewColumnInfo, MainContext, MainThreadNotebookDocumentsShape, MainThreadNotebookEditorsShape, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
import { ILogService } from 'vs/platform/log/common/log';
import { CommandsConverter, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import { CellEditType, ICellRange, INotebookExclusiveDocumentFilter, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookDataDto, NullablePartialNotebookCellMetadata, IImmediateCellEditOperation } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { CellEditType, INotebookExclusiveDocumentFilter, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookDataDto, NullablePartialNotebookCellMetadata, IImmediateCellEditOperation } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import type * as vscode from 'vscode';
import { ResourceMap } from 'vs/base/common/map';
import { ExtHostCell, ExtHostNotebookDocument } from './extHostNotebookDocument';
......@@ -30,162 +28,6 @@ import { hash } from 'vs/base/common/hash';
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import { Cache } from 'vs/workbench/api/common/cache';
class ExtHostWebviewCommWrapper extends Disposable {
private readonly _onDidReceiveDocumentMessage = new Emitter<any>();
private readonly _rendererIdToEmitters = new Map<string, Emitter<any>>();
constructor(
private _editorId: string,
public uri: URI,
private _proxy: MainThreadNotebookShape,
private _webviewInitData: WebviewInitData,
public document: ExtHostNotebookDocument,
) {
super();
}
public onDidReceiveMessage(forRendererId: string | undefined, message: any) {
this._onDidReceiveDocumentMessage.fire(message);
if (forRendererId !== undefined) {
this._rendererIdToEmitters.get(forRendererId)?.fire(message);
}
}
public readonly contentProviderComm: vscode.NotebookCommunication = {
editorId: this._editorId,
onDidReceiveMessage: this._onDidReceiveDocumentMessage.event,
postMessage: (message: any) => this._proxy.$postMessage(this._editorId, undefined, message),
asWebviewUri: (uri: vscode.Uri) => this._asWebviewUri(uri),
};
public getRendererComm(rendererId: string): vscode.NotebookCommunication {
const emitter = new Emitter<any>();
this._rendererIdToEmitters.set(rendererId, emitter);
return {
editorId: this._editorId,
onDidReceiveMessage: emitter.event,
postMessage: (message: any) => this._proxy.$postMessage(this._editorId, rendererId, message),
asWebviewUri: (uri: vscode.Uri) => this._asWebviewUri(uri),
};
}
private _asWebviewUri(localResource: vscode.Uri): vscode.Uri {
return asWebviewUri(this._webviewInitData, this._editorId, localResource);
}
}
export class ExtHostNotebookKernelProviderAdapter extends Disposable {
private _kernelToFriendlyId = new ResourceMap<Map<vscode.NotebookKernel, string>>();
private _friendlyIdToKernel = new ResourceMap<Map<string, vscode.NotebookKernel>>();
constructor(
private readonly _proxy: MainThreadNotebookShape,
private readonly _handle: number,
private readonly _extension: IExtensionDescription,
private readonly _provider: vscode.NotebookKernelProvider
) {
super();
if (this._provider.onDidChangeKernels) {
this._register(this._provider.onDidChangeKernels((e: vscode.NotebookDocument | undefined) => {
const uri = e?.uri;
this._proxy.$onNotebookKernelChange(this._handle, uri);
}));
}
}
async provideKernels(document: ExtHostNotebookDocument, token: vscode.CancellationToken): Promise<INotebookKernelInfoDto2[]> {
const data = await this._provider.provideKernels(document.notebookDocument, token) || [];
const newMap = new Map<vscode.NotebookKernel, string>();
let kernel_unique_pool = 0;
const kernelFriendlyIdCache = new Set<string>();
const kernelToFriendlyId = this._kernelToFriendlyId.get(document.uri);
const transformedData: INotebookKernelInfoDto2[] = data.map(kernel => {
let friendlyId = kernelToFriendlyId?.get(kernel);
if (friendlyId === undefined) {
if (kernel.id && kernelFriendlyIdCache.has(kernel.id)) {
friendlyId = `${this._extension.identifier.value}_${kernel.id}_${kernel_unique_pool++}`;
} else {
friendlyId = `${this._extension.identifier.value}_${kernel.id || UUID.generateUuid()}`;
}
}
newMap.set(kernel, friendlyId);
return {
id: kernel.id,
friendlyId: friendlyId,
label: kernel.label,
extension: this._extension.identifier,
extensionLocation: this._extension.extensionLocation,
providerHandle: this._handle,
description: kernel.description,
detail: kernel.detail,
isPreferred: kernel.isPreferred,
preloads: kernel.preloads?.map(preload => {
// todo@connor4312: back compat on 2020-04-12, remove after transition
if (URI.isUri(preload)) {
preload = { uri: preload, provides: [] };
}
return {
uri: preload.uri, provides: typeof preload.provides === 'string'
? [preload.provides]
: preload.provides === undefined
? []
: preload.provides
};
}),
supportedLanguages: kernel.supportedLanguages,
implementsInterrupt: !!kernel.interrupt
};
});
this._kernelToFriendlyId.set(document.uri, newMap);
const friendlyIdToKernel = new Map<string, vscode.NotebookKernel>();
newMap.forEach((value, key) => {
friendlyIdToKernel.set(value, key);
});
this._friendlyIdToKernel.set(document.uri, friendlyIdToKernel);
return transformedData;
}
getKernelByFriendlyId(uri: URI, kernelId: string) {
return this._friendlyIdToKernel.get(uri)?.get(kernelId);
}
async resolveNotebook(kernelId: string, document: ExtHostNotebookDocument, webview: vscode.NotebookCommunication, token: CancellationToken) {
const kernel = this._friendlyIdToKernel.get(document.uri)?.get(kernelId);
if (kernel && this._provider.resolveKernel) {
return this._provider.resolveKernel(kernel, document.notebookDocument, webview, token);
}
}
async executeNotebook(kernelId: string, document: ExtHostNotebookDocument, cellRange: ICellRange[]): Promise<void> {
const kernel = this._friendlyIdToKernel.get(document.uri)?.get(kernelId);
if (!kernel) {
return;
}
const extCellRange = cellRange.map(c => typeConverters.NotebookRange.to(c));
return kernel.executeCellsRequest(document.notebookDocument, extCellRange);
}
async interruptNotebookExecution(kernelId: string, document: ExtHostNotebookDocument): Promise<void> {
const kernel = this._friendlyIdToKernel.get(document.uri)?.get(kernelId);
if (!kernel || !kernel.interrupt) {
return;
}
return kernel.interrupt(document.notebookDocument);
}
}
export class NotebookEditorDecorationType {
......@@ -213,7 +55,6 @@ type NotebookContentProviderData = {
};
export class ExtHostNotebookController implements ExtHostNotebookShape {
private static _notebookKernelProviderHandlePool: number = 0;
private static _notebookStatusBarItemProviderHandlePool: number = 0;
private readonly _notebookProxy: MainThreadNotebookShape;
......@@ -221,11 +62,9 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
private readonly _notebookEditorsProxy: MainThreadNotebookEditorsShape;
private readonly _notebookContentProviders = new Map<string, NotebookContentProviderData>();
private readonly _notebookKernelProviders = new Map<number, ExtHostNotebookKernelProviderAdapter>();
private readonly _notebookStatusBarItemProviders = new Map<number, vscode.NotebookCellStatusBarItemProvider>();
private readonly _documents = new ResourceMap<ExtHostNotebookDocument>();
private readonly _editors = new Map<string, ExtHostNotebookEditor>();
private readonly _webviewComm = new Map<string, ExtHostWebviewCommWrapper>();
private readonly _commandsConverter: CommandsConverter;
private readonly _onDidChangeNotebookEditorSelection = new Emitter<vscode.NotebookEditorSelectionChangeEvent>();
readonly onDidChangeNotebookEditorSelection = this._onDidChangeNotebookEditorSelection.event;
......@@ -259,8 +98,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
onDidCloseNotebookDocument: Event<vscode.NotebookDocument> = this._onDidCloseNotebookDocument.event;
private _onDidSaveNotebookDocument = new Emitter<vscode.NotebookDocument>();
onDidSaveNotebookDocument: Event<vscode.NotebookDocument> = this._onDidSaveNotebookDocument.event;
private _onDidChangeActiveNotebookKernel = new Emitter<{ document: vscode.NotebookDocument, kernel: vscode.NotebookKernel | undefined; }>();
onDidChangeActiveNotebookKernel = this._onDidChangeActiveNotebookKernel.event;
private _onDidChangeVisibleNotebookEditors = new Emitter<vscode.NotebookEditor[]>();
onDidChangeVisibleNotebookEditors = this._onDidChangeVisibleNotebookEditors.event;
......@@ -273,7 +110,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
commands: ExtHostCommands,
private _textDocumentsAndEditors: ExtHostDocumentsAndEditors,
private _textDocuments: ExtHostDocuments,
private readonly _webviewInitData: WebviewInitData,
private readonly logService: ILogService,
private readonly _extensionStoragePaths: IExtensionStoragePaths,
) {
......@@ -388,22 +224,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
});
}
registerNotebookKernelProvider(extension: IExtensionDescription, selector: vscode.NotebookDocumentFilter, provider: vscode.NotebookKernelProvider) {
const handle = ExtHostNotebookController._notebookKernelProviderHandlePool++;
const adapter = new ExtHostNotebookKernelProviderAdapter(this._notebookProxy, handle, extension, provider);
this._notebookKernelProviders.set(handle, adapter);
this._notebookProxy.$registerNotebookKernelProvider({ id: extension.identifier, location: extension.extensionLocation, description: extension.description }, handle, {
viewType: selector.viewType,
filenamePattern: selector.filenamePattern ? typeConverters.NotebookExclusiveDocumentPattern.from(selector.filenamePattern) : undefined
});
return new extHostTypes.Disposable(() => {
adapter.dispose();
this._notebookKernelProviders.delete(handle);
this._notebookProxy.$unregisterNotebookKernelProvider(handle);
});
}
registerNotebookCellStatusBarItemProvider(extension: IExtensionDescription, selector: vscode.NotebookDocumentFilter, provider: vscode.NotebookCellStatusBarItemProvider) {
const handle = ExtHostNotebookController._notebookStatusBarItemProviderHandlePool++;
const eventHandle = typeof provider.onDidChangeCellStatusBarItems === 'function' ? ExtHostNotebookController._notebookStatusBarItemProviderHandlePool++ : undefined;
......@@ -442,21 +262,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
return assertIsDefined(document?.notebookDocument);
}
private _withAdapter<T>(handle: number, uri: UriComponents, callback: (adapter: ExtHostNotebookKernelProviderAdapter, document: ExtHostNotebookDocument) => Promise<T>) {
const document = this._documents.get(URI.revive(uri));
if (!document) {
return [];
}
const provider = this._notebookKernelProviders.get(handle);
if (!provider) {
return [];
}
return callback(provider, document);
}
async showNotebookDocument(notebookOrUri: vscode.NotebookDocument | URI, options?: vscode.NotebookDocumentShowOptions): Promise<vscode.NotebookEditor> {
......@@ -492,22 +297,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
}
}
async $provideNotebookKernels(handle: number, uri: UriComponents, token: CancellationToken): Promise<INotebookKernelInfoDto2[]> {
return this._withAdapter<INotebookKernelInfoDto2[]>(handle, uri, (adapter, document) => {
return adapter.provideKernels(document, token);
});
}
async $resolveNotebookKernel(handle: number, editorId: string, uri: UriComponents, kernelId: string, token: CancellationToken): Promise<void> {
await this._withAdapter<void>(handle, uri, async (adapter, document) => {
const webComm = this._webviewComm.get(editorId);
if (webComm) {
await adapter.resolveNotebook(kernelId, document, webComm.contentProviderComm, token);
}
});
}
async $provideNotebookCellStatusBarItems(handle: number, uri: UriComponents, index: number, token: CancellationToken): Promise<INotebookCellStatusBarListDto | undefined> {
const provider = this._notebookStatusBarItemProviders.get(handle);
const revivedUri = URI.revive(uri);
......@@ -539,27 +328,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
this._statusBarCache.delete(cacheId);
}
async $resolveNotebookEditor(viewType: string, uri: UriComponents, editorId: string): Promise<void> {
const provider = this._notebookContentProviders.get(viewType);
const revivedUri = URI.revive(uri);
const document = this._documents.get(revivedUri);
if (!document || !provider) {
return;
}
let webComm = this._webviewComm.get(editorId);
if (!webComm) {
webComm = new ExtHostWebviewCommWrapper(editorId, revivedUri, this._notebookProxy, this._webviewInitData, document);
this._webviewComm.set(editorId, webComm);
}
}
async $executeNotebookKernelFromProvider(handle: number, uri: UriComponents, kernelId: string, cellRange: ICellRange[]): Promise<void> {
await this._withAdapter(handle, uri, async (adapter, document) => {
return adapter.executeNotebook(kernelId, document, cellRange);
});
}
// --- serialize/deserialize
private _handlePool = 0;
......@@ -604,26 +372,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
return VSBuffer.wrap(bytes);
}
async $cancelNotebookCellExecution(handle: number, uri: UriComponents, kernelId: string, cellRange: ICellRange[]): Promise<void> {
await this._withAdapter(handle, uri, async (adapter, document) => {
return adapter.interruptNotebookExecution(kernelId, document);
});
const document = this._documents.get(URI.revive(uri));
if (!document) {
return;
}
for (let range of cellRange) {
for (let i = range.start; i < range.end; i++) {
const cell = document.getCellFromIndex(i);
if (cell) {
this.cancelOneNotebookCellExecution(cell);
}
}
}
}
cancelOneNotebookCellExecution(cell: ExtHostCell): void {
const execution = this._activeExecutions.get(cell.uri);
execution?.cancel();
......@@ -669,24 +417,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
return backup.id;
}
$acceptNotebookActiveKernelChange(event: { uri: UriComponents, providerHandle: number | undefined, kernelFriendlyId: string | undefined; }) {
if (event.providerHandle !== undefined) {
this._withAdapter(event.providerHandle, event.uri, async (adapter, document) => {
const kernel = event.kernelFriendlyId ? adapter.getKernelByFriendlyId(URI.revive(event.uri), event.kernelFriendlyId) : undefined;
this._editors.forEach(editor => {
if (editor.notebookData === document) {
editor._acceptKernel(kernel);
}
});
this._onDidChangeActiveNotebookKernel.fire({ document: document.notebookDocument, kernel });
});
}
}
$onDidReceiveMessage(editorId: string, forRendererType: string | undefined, message: any): void {
this._webviewComm.get(editorId)?.onDidReceiveMessage(forRendererType, message);
}
$acceptModelChanged(uri: UriComponents, event: NotebookCellsChangedEventDto, isDirty: boolean): void {
const document = this._getNotebookDocument(URI.revive(uri));
document.acceptModelChanged(event, isDirty);
......@@ -758,14 +488,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape {
throw new Error(`editor with id ALREADY EXSIST: ${editorId}`);
}
const revivedUri = document.uri;
let webComm = this._webviewComm.get(editorId);
if (!webComm) {
webComm = new ExtHostWebviewCommWrapper(editorId, revivedUri, this._notebookProxy, this._webviewInitData, document);
this._webviewComm.set(editorId, webComm);
}
const editor = new ExtHostNotebookEditor(
editorId,
this._notebookEditorsProxy,
......
......@@ -89,8 +89,6 @@ export class ExtHostNotebookEditor {
private _viewColumn?: vscode.ViewColumn;
private _visible: boolean = false;
private _kernel?: vscode.NotebookKernel;
private readonly _hasDecorationsForKey = new Set<string>();
private _editor?: vscode.NotebookEditor;
......@@ -136,9 +134,6 @@ export class ExtHostNotebookEditor {
callback(edit);
return that._applyEdit(edit.finalize());
},
get kernel() {
return that._kernel;
},
setDecorations(decorationType, range) {
return that.setDecorations(decorationType, range);
}
......@@ -147,10 +142,6 @@ export class ExtHostNotebookEditor {
return this._editor;
}
_acceptKernel(kernel?: vscode.NotebookKernel) {
this._kernel = kernel;
}
get visible(): boolean {
return this._visible;
}
......
......@@ -216,7 +216,7 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
}
try {
obj.controller.executeHandler.call(obj.controller, cells, obj.controller);
await obj.controller.executeHandler.call(obj.controller, cells, obj.controller);
} catch (err) {
//
console.error(err);
......@@ -234,7 +234,7 @@ export class ExtHostNotebookKernels implements ExtHostNotebookKernelsShape {
throw new Error('MISSING notebook');
}
if (obj.controller.interruptHandler) {
obj.controller.interruptHandler.call(obj.controller);
await obj.controller.interruptHandler.call(obj.controller);
}
// we do both? interrupt and cancellation or should we be selective?
......
......@@ -22,6 +22,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { configureKernelIcon, selectKernelIcon } from 'vs/workbench/contrib/notebook/browser/notebookIcons';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
import { NotebookViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
registerAction2(class extends Action2 {
constructor() {
......@@ -89,7 +90,7 @@ registerAction2(class extends Action2 {
const availableKernels = await editor.beginComputeContributedKernels();
const selectedKernel = availableKernels.length ? availableKernels.find(
kernel => kernel.id && context?.id && kernel.id === context?.id && kernel.extension.value === context?.extension
kernel => kernel.id && context?.id && kernel.id === context?.id && ExtensionIdentifier.equals(kernel.extension, context?.extension)
) : undefined;
if (selectedKernel) {
......
......@@ -26,7 +26,6 @@ import { IEditorDropService } from 'vs/workbench/services/editor/browser/editorD
import { IEditorGroup, IEditorGroupsService, GroupsOrder } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { NotebookEditorOptions, NOTEBOOK_EDITOR_ID } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { IBorrowValue, INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService';
import { clearMarks, getAndClearMarks, mark } from 'vs/workbench/contrib/notebook/common/notebookPerformance';
import { IFileService } from 'vs/platform/files/common/files';
......@@ -59,7 +58,6 @@ export class NotebookEditor extends EditorPane {
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
@IEditorDropService private readonly _editorDropService: IEditorDropService,
@INotificationService private readonly _notificationService: INotificationService,
@INotebookService private readonly _notebookService: INotebookService,
@INotebookEditorService private readonly _notebookWidgetService: INotebookEditorService,
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
@IFileService private readonly fileService: IFileService,
......@@ -189,8 +187,7 @@ export class NotebookEditor extends EditorPane {
return;
}
await this._notebookService.resolveNotebookEditor(model.viewType, model.resource, this._widget.value!.getId());
mark(input.resource, 'webviewCommLoaded');
const viewState = this._loadNotebookEditorViewState(input);
......
......@@ -1072,13 +1072,6 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
}
});
this._localStore.add(this._webview.onMessage(e => {
if (this.viewModel) {
this.notebookService.onDidReceiveMessage(this.viewModel.viewType, this.getId(), e.forRenderer, e.message);
this._onDidReceiveMessage.fire(e);
}
}));
resolve(this._webview);
});
......
......@@ -739,22 +739,6 @@ export class NotebookService extends Disposable implements INotebookService, IEd
return ret;
}
// --- data provider IPC (deprecated)
async resolveNotebookEditor(viewType: string, uri: URI, editorId: string): Promise<void> {
const entry = this._notebookProviders.get(viewType);
if (entry instanceof ComplexNotebookProviderInfo) {
entry.controller.resolveNotebookEditor(viewType, uri, editorId);
}
}
onDidReceiveMessage(viewType: string, editorId: string, rendererType: string | undefined, message: any): void {
const provider = this._notebookProviders.get(viewType);
if (provider instanceof ComplexNotebookProviderInfo) {
return provider.controller.onDidReceiveMessage(editorId, rendererType, message);
}
}
// --- copy & paste
setToCopy(items: NotebookCellTextModel[], isCopy: boolean) {
......
......@@ -22,8 +22,6 @@ export const INotebookService = createDecorator<INotebookService>('notebookServi
export interface IMainNotebookController {
viewOptions?: { displayName: string; filenamePattern: (string | IRelativePattern | INotebookExclusiveDocumentFilter)[]; exclusive: boolean; };
options: TransientOptions;
resolveNotebookEditor(viewType: string, uri: URI, editorId: string): Promise<void>;
onDidReceiveMessage(editorId: string, rendererType: string | undefined, message: any): void;
open(uri: URI, backupId: string | undefined, untitledDocumentData: VSBuffer | undefined, token: CancellationToken): Promise<{ data: NotebookDataDto, transientOptions: TransientOptions; }>;
save(uri: URI, token: CancellationToken): Promise<boolean>;
......@@ -92,11 +90,6 @@ export interface INotebookService {
getContributedNotebookProvider(viewType: string): NotebookProviderInfo | undefined;
getNotebookProviderResourceRoots(): URI[];
onDidReceiveMessage(viewType: string, editorId: string, rendererType: string | undefined, message: unknown): void;
setToCopy(items: NotebookCellTextModel[], isCopy: boolean): void;
getToCopy(): { items: NotebookCellTextModel[], isCopy: boolean; } | undefined;
// editor events
resolveNotebookEditor(viewType: string, uri: URI, editorId: string): Promise<void>;
}
......@@ -54,7 +54,7 @@ suite('NotebookCell#Document', function () {
return URI.from({ scheme: 'test', path: generateUuid() });
}
};
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, { isExtensionDevelopmentDebug: false, webviewCspSource: '', webviewResourceRoot: '' }, new NullLogService(), extHostStoragePaths);
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, new NullLogService(), extHostStoragePaths);
let reg = extHostNotebooks.registerNotebookContentProvider(nullExtensionDescription, 'test', new class extends mock<vscode.NotebookContentProvider>() {
// async openNotebook() { }
});
......
......@@ -51,7 +51,7 @@ suite('NotebookConcatDocument', function () {
return URI.from({ scheme: 'test', path: generateUuid() });
}
};
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, { isExtensionDevelopmentDebug: false, webviewCspSource: '', webviewResourceRoot: '' }, new NullLogService(), extHostStoragePaths);
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, new NullLogService(), extHostStoragePaths);
let reg = extHostNotebooks.registerNotebookContentProvider(nullExtensionDescription, 'test', new class extends mock<vscode.NotebookContentProvider>() {
// async openNotebook() { }
});
......@@ -70,14 +70,12 @@ suite('NotebookConcatDocument', function () {
}],
versionId: 0
}],
addedEditors: [
{
documentUri: notebookUri,
id: '_notebook_editor_0',
selections: [{ start: 0, end: 1 }],
visibleRanges: []
}
]
addedEditors: [{
documentUri: notebookUri,
id: '_notebook_editor_0',
selections: [{ start: 0, end: 1 }],
visibleRanges: []
}]
});
extHostNotebooks.$acceptDocumentAndEditorsDelta({ newActiveEditor: '_notebook_editor_0' });
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { TestRPCProtocol } from 'vs/workbench/test/browser/api/testRPCProtocol';
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { NullLogService } from 'vs/platform/log/common/log';
import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
import { ExtHostNotebookDocument } from 'vs/workbench/api/common/extHostNotebookDocument';
import { URI } from 'vs/base/common/uri';
import { CellKind, CellUri } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { nullExtensionDescription } from 'vs/workbench/services/extensions/common/extensions';
import * as vscode from 'vscode';
import { mock } from 'vs/workbench/test/common/workbenchTestServices';
import { MainContext, MainThreadCommandsShape, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
import { generateUuid } from 'vs/base/common/uuid';
import { CancellationToken } from 'vs/base/common/cancellation';
suite('NotebookKernel', function () {
let rpcProtocol: TestRPCProtocol;
let notebook: ExtHostNotebookDocument;
let extHostDocumentsAndEditors: ExtHostDocumentsAndEditors;
let extHostDocuments: ExtHostDocuments;
let extHostNotebooks: ExtHostNotebookController;
const notebookUri = URI.parse('test:///notebook.file');
const disposables = new DisposableStore();
setup(async function () {
disposables.clear();
rpcProtocol = new TestRPCProtocol();
rpcProtocol.set(MainContext.MainThreadCommands, new class extends mock<MainThreadCommandsShape>() {
override $registerCommand() { }
});
rpcProtocol.set(MainContext.MainThreadNotebook, new class extends mock<MainThreadNotebookShape>() {
async override $registerNotebookProvider() { }
async override $unregisterNotebookProvider() { }
async override $registerNotebookKernelProvider() { }
async override $unregisterNotebookKernelProvider() { }
});
extHostDocumentsAndEditors = new ExtHostDocumentsAndEditors(rpcProtocol, new NullLogService());
extHostDocuments = new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors);
const extHostStoragePaths = new class extends mock<IExtensionStoragePaths>() {
override workspaceValue() {
return URI.from({ scheme: 'test', path: generateUuid() });
}
};
extHostNotebooks = new ExtHostNotebookController(rpcProtocol, new ExtHostCommands(rpcProtocol, new NullLogService()), extHostDocumentsAndEditors, extHostDocuments, { isExtensionDevelopmentDebug: false, webviewCspSource: '', webviewResourceRoot: '' }, new NullLogService(), extHostStoragePaths);
let reg = extHostNotebooks.registerNotebookContentProvider(nullExtensionDescription, 'test', new class extends mock<vscode.NotebookContentProvider>() {
// async openNotebook() { }
});
const kernels = [new class extends mock<vscode.NotebookKernel>() {
override id = 'first';
}, new class extends mock<vscode.NotebookKernel>() {
override id = 'second';
}];
let kernelReg = extHostNotebooks.registerNotebookKernelProvider(nullExtensionDescription, { viewType: 'test' }, new class extends mock<vscode.NotebookKernelProvider>() {
async override provideKernels() { return kernels; }
});
// init
extHostNotebooks.$acceptDocumentAndEditorsDelta({
addedDocuments: [{
uri: notebookUri,
viewType: 'test',
cells: [{
handle: 0,
uri: CellUri.generate(notebookUri, 0),
source: ['console.log'],
eol: '\n',
language: 'javascript',
cellKind: CellKind.Code,
outputs: [],
}],
versionId: 0
}],
addedEditors: [
{
documentUri: notebookUri,
id: '_notebook_editor_0',
selections: [{ start: 0, end: 1 }],
visibleRanges: []
}
]
});
extHostNotebooks.$acceptDocumentAndEditorsDelta({ newActiveEditor: '_notebook_editor_0' });
notebook = extHostNotebooks.notebookDocuments[0]!;
disposables.add(reg);
disposables.add(kernelReg);
disposables.add(notebook);
disposables.add(extHostDocuments);
});
test('provide kernels', async function () {
const dto = await extHostNotebooks.$provideNotebookKernels(0, notebook.uri, CancellationToken.None);
assert.deepStrictEqual(dto.map(kernel => kernel.id), ['first', 'second']);
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册