Archived
Initial implementation for VSCode Notebook support (#17885)
This commit is contained in:
@@ -10,6 +10,9 @@ import * as fs from 'fs';
|
|||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
|
const NBFORMAT = 4;
|
||||||
|
const NBFORMAT_MINOR = 2;
|
||||||
|
|
||||||
export class CellTypes {
|
export class CellTypes {
|
||||||
public static readonly Code = 'code';
|
public static readonly Code = 'code';
|
||||||
public static readonly Markdown = 'markdown';
|
public static readonly Markdown = 'markdown';
|
||||||
@@ -29,8 +32,8 @@ export const pySparkNotebookContent: azdata.nb.INotebookContents = {
|
|||||||
display_name: 'PySpark'
|
display_name: 'PySpark'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 2
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
export const notebookContentForCellLanguageTest: azdata.nb.INotebookContents = {
|
export const notebookContentForCellLanguageTest: azdata.nb.INotebookContents = {
|
||||||
@@ -46,8 +49,8 @@ export const notebookContentForCellLanguageTest: azdata.nb.INotebookContents = {
|
|||||||
display_name: ''
|
display_name: ''
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 2
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
export const pythonNotebookMultipleCellsContent: azdata.nb.INotebookContents = {
|
export const pythonNotebookMultipleCellsContent: azdata.nb.INotebookContents = {
|
||||||
@@ -78,8 +81,8 @@ export const pythonNotebookMultipleCellsContent: azdata.nb.INotebookContents = {
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 2
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sqlNotebookContent: azdata.nb.INotebookContents = {
|
export const sqlNotebookContent: azdata.nb.INotebookContents = {
|
||||||
@@ -95,8 +98,8 @@ export const sqlNotebookContent: azdata.nb.INotebookContents = {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 2
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sqlNotebookMultipleCellsContent: azdata.nb.INotebookContents = {
|
export const sqlNotebookMultipleCellsContent: azdata.nb.INotebookContents = {
|
||||||
@@ -122,8 +125,8 @@ export const sqlNotebookMultipleCellsContent: azdata.nb.INotebookContents = {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 2
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
export const pySparkKernelMetadata = {
|
export const pySparkKernelMetadata = {
|
||||||
|
|||||||
@@ -93,3 +93,7 @@ export const SQL_PROVIDER = 'MSSQL';
|
|||||||
export const USER = 'user';
|
export const USER = 'user';
|
||||||
export const AUTHTYPE = 'authenticationType';
|
export const AUTHTYPE = 'authenticationType';
|
||||||
export const INTEGRATED_AUTH = 'integrated';
|
export const INTEGRATED_AUTH = 'integrated';
|
||||||
|
|
||||||
|
// The version of the notebook file format that we support
|
||||||
|
export const NBFORMAT = 4;
|
||||||
|
export const NBFORMAT_MINOR = 2;
|
||||||
|
|||||||
@@ -885,8 +885,8 @@ export class JupyterServerInstallation implements IJupyterServerInstallation {
|
|||||||
name: 'python3'
|
name: 'python3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: constants.NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: constants.NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
await vscode.commands.executeCommand('_notebook.command.new', {
|
await vscode.commands.executeCommand('_notebook.command.new', {
|
||||||
|
|||||||
@@ -147,8 +147,8 @@ describe('Notebook URI Handler', function (): void {
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: constants.NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: constants.NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
await fs.writeFile(notebookPath, JSON.stringify(notebookContent));
|
await fs.writeFile(notebookPath, JSON.stringify(notebookContent));
|
||||||
|
|||||||
Vendored
+8
@@ -38,6 +38,10 @@ declare module 'azdata' {
|
|||||||
nbKernelAlias?: string
|
nbKernelAlias?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ICellOutput {
|
||||||
|
id?: string; // Unique identifier for this cell output
|
||||||
|
}
|
||||||
|
|
||||||
export interface IExecuteResult {
|
export interface IExecuteResult {
|
||||||
data: any;
|
data: any;
|
||||||
}
|
}
|
||||||
@@ -48,6 +52,10 @@ declare module 'azdata' {
|
|||||||
data: any;
|
data: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IExecuteRequest {
|
||||||
|
notebookUri?: vscode.Uri; // URI of the notebook document that is sending this execute request
|
||||||
|
}
|
||||||
|
|
||||||
export interface INotebookMetadata {
|
export interface INotebookMetadata {
|
||||||
connection_name?: string;
|
connection_name?: string;
|
||||||
multi_connection_mode?: boolean;
|
multi_connection_mode?: boolean;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import { localize } from 'vs/nls';
|
import { localize } from 'vs/nls';
|
||||||
|
|
||||||
// Contains vs strings that are nonnative to vscode that need to be translated.
|
// Contains vs strings that are non-native to vscode that need to be translated.
|
||||||
|
|
||||||
export const issueReporterMainAzuredatastudio = localize('azuredatastudio', "Azure Data Studio");
|
export const issueReporterMainAzuredatastudio = localize('azuredatastudio', "Azure Data Studio");
|
||||||
export const updateConfigContributionDefault = localize('default', "Enable automatic update checks. Azure Data Studio will check for updates automatically and periodically.");
|
export const updateConfigContributionDefault = localize('default', "Enable automatic update checks. Azure Data Studio will check for updates automatically and periodically.");
|
||||||
@@ -47,3 +47,4 @@ export const watermarkNewNotebook = localize('watermark.newNotebook', "New Noteb
|
|||||||
export const desktopContributionMiinstallVsix = localize({ key: 'miinstallVsix', comment: ['&& denotes a mnemonic'] }, "Install Extension from VSIX Package");
|
export const desktopContributionMiinstallVsix = localize({ key: 'miinstallVsix', comment: ['&& denotes a mnemonic'] }, "Install Extension from VSIX Package");
|
||||||
export const workspaceTrustDescription = localize('workspace.trust.description', "Controls whether or not workspace trust is enabled within Azure Data Studio.");
|
export const workspaceTrustDescription = localize('workspace.trust.description', "Controls whether or not workspace trust is enabled within Azure Data Studio.");
|
||||||
export function workspaceTrustEmptyWindowDescription(settingName: string): string { return localize('workspace.trust.emptyWindow.description', "Controls whether or not the empty window is trusted by default within Azure Data Studio. When used with `#{0}#`, you can enable the full functionality of Azure Data Studio without prompting in an empty window.", settingName); }
|
export function workspaceTrustEmptyWindowDescription(settingName: string): string { return localize('workspace.trust.emptyWindow.description', "Controls whether or not the empty window is trusted by default within Azure Data Studio. When used with `#{0}#`, you can enable the full functionality of Azure Data Studio without prompting in an empty window.", settingName); }
|
||||||
|
export const functionalityNotSupportedError = localize('vscodeFunctionalityNotSupportedError', "This VS Code functionality is not supported in Azure Data Studio.");
|
||||||
|
|||||||
@@ -17,6 +17,10 @@ import { LocalContentManager } from 'sql/workbench/services/notebook/common/loca
|
|||||||
import { Deferred } from 'sql/base/common/promise';
|
import { Deferred } from 'sql/base/common/promise';
|
||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import type { FutureInternal } from 'sql/workbench/services/notebook/browser/interfaces';
|
import type { FutureInternal } from 'sql/workbench/services/notebook/browser/interfaces';
|
||||||
|
import { Registry } from 'vs/platform/registry/common/platform';
|
||||||
|
import { INotebookProviderRegistry, NotebookProviderRegistryId } from 'sql/workbench/services/notebook/common/notebookRegistry';
|
||||||
|
|
||||||
|
const notebookRegistry = Registry.as<INotebookProviderRegistry>(NotebookProviderRegistryId);
|
||||||
|
|
||||||
@extHostNamedCustomer(SqlMainContext.MainThreadNotebook)
|
@extHostNamedCustomer(SqlMainContext.MainThreadNotebook)
|
||||||
export class MainThreadNotebook extends Disposable implements MainThreadNotebookShape {
|
export class MainThreadNotebook extends Disposable implements MainThreadNotebookShape {
|
||||||
@@ -96,7 +100,10 @@ export class MainThreadNotebook extends Disposable implements MainThreadNotebook
|
|||||||
if (future) {
|
if (future) {
|
||||||
future.onDone(done);
|
future.onDone(done);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public $updateProviderDescriptionLanguages(providerId: string, languages: string[]): void {
|
||||||
|
notebookRegistry.updateProviderDescriptionLanguages(providerId, languages);
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,207 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import type * as vscode from 'vscode';
|
||||||
|
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||||
|
import { INotebookKernelDto2 } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
|
import { Emitter, Event } from 'vs/base/common/event';
|
||||||
|
import * as extHostTypeConverters from 'vs/workbench/api/common/extHostTypeConverters';
|
||||||
|
import { Deferred } from 'sql/base/common/promise';
|
||||||
|
|
||||||
|
type SelectionChangedEvent = { selected: boolean, notebook: vscode.NotebookDocument; };
|
||||||
|
type MessageReceivedEvent = { editor: vscode.NotebookEditor, message: any; };
|
||||||
|
type ExecutionHandler = (cells: vscode.NotebookCell[], notebook: vscode.NotebookDocument, controller: vscode.NotebookController) => void | Thenable<void>;
|
||||||
|
type InterruptHandler = (notebook: vscode.NotebookDocument) => void | Promise<void>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A VS Code Notebook Controller that is used as part of converting VS Code notebook extension APIs into ADS equivalents.
|
||||||
|
*/
|
||||||
|
export class ADSNotebookController implements vscode.NotebookController {
|
||||||
|
private readonly _kernelData: INotebookKernelDto2;
|
||||||
|
private _interruptHandler: (notebook: vscode.NotebookDocument) => void | Promise<void>;
|
||||||
|
|
||||||
|
private readonly _onDidChangeSelection = new Emitter<SelectionChangedEvent>();
|
||||||
|
private readonly _onDidReceiveMessage = new Emitter<MessageReceivedEvent>();
|
||||||
|
|
||||||
|
private readonly _languagesAdded = new Deferred<void>();
|
||||||
|
private readonly _executionHandlerAdded = new Deferred<void>();
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private _extension: IExtensionDescription,
|
||||||
|
private _id: string,
|
||||||
|
private _viewType: string,
|
||||||
|
private _label: string,
|
||||||
|
private _addLanguagesHandler: (providerId, languages) => void,
|
||||||
|
private _handler?: ExecutionHandler,
|
||||||
|
preloads?: vscode.NotebookRendererScript[]
|
||||||
|
) {
|
||||||
|
this._kernelData = {
|
||||||
|
id: `${this._extension.identifier.value}/${this._id}`,
|
||||||
|
notebookType: this._viewType,
|
||||||
|
extensionId: this._extension.identifier,
|
||||||
|
extensionLocation: this._extension.extensionLocation,
|
||||||
|
label: this._label || this._extension.identifier.value,
|
||||||
|
preloads: preloads ? preloads.map(extHostTypeConverters.NotebookRendererScript.from) : []
|
||||||
|
};
|
||||||
|
if (this._handler) {
|
||||||
|
this._executionHandlerAdded.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get languagesAdded(): Promise<void> {
|
||||||
|
return this._languagesAdded.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get executionHandlerAdded(): Promise<void> {
|
||||||
|
return this._executionHandlerAdded.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get id(): string { return this._id; }
|
||||||
|
|
||||||
|
public get notebookType(): string { return this._viewType; }
|
||||||
|
|
||||||
|
public get onDidChangeSelectedNotebooks(): Event<SelectionChangedEvent> {
|
||||||
|
return this._onDidChangeSelection.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get onDidReceiveMessage(): Event<MessageReceivedEvent> {
|
||||||
|
return this._onDidReceiveMessage.event;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get label(): string {
|
||||||
|
return this._kernelData.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set label(value: string) {
|
||||||
|
this._kernelData.label = value ?? this._extension.displayName ?? this._extension.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get detail(): string {
|
||||||
|
return this._kernelData.detail ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public set detail(value: string) {
|
||||||
|
this._kernelData.detail = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get description(): string {
|
||||||
|
return this._kernelData.description ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public set description(value: string) {
|
||||||
|
this._kernelData.description = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get supportedLanguages(): string[] | undefined {
|
||||||
|
return this._kernelData.supportedLanguages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set supportedLanguages(value: string[]) {
|
||||||
|
this._kernelData.supportedLanguages = value;
|
||||||
|
this._addLanguagesHandler(this._viewType, value);
|
||||||
|
this._languagesAdded.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get supportsExecutionOrder(): boolean {
|
||||||
|
return this._kernelData.supportsExecutionOrder ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set supportsExecutionOrder(value: boolean) {
|
||||||
|
this._kernelData.supportsExecutionOrder = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get rendererScripts(): vscode.NotebookRendererScript[] {
|
||||||
|
return this._kernelData.preloads ? this._kernelData.preloads.map(extHostTypeConverters.NotebookRendererScript.to) : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public get executeHandler(): ExecutionHandler {
|
||||||
|
return this._handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set executeHandler(value: ExecutionHandler) {
|
||||||
|
this._handler = value;
|
||||||
|
this._executionHandlerAdded.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get interruptHandler(): InterruptHandler {
|
||||||
|
return this._interruptHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set interruptHandler(value: InterruptHandler) {
|
||||||
|
this._interruptHandler = value;
|
||||||
|
this._kernelData.supportsInterrupt = Boolean(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public createNotebookCellExecution(cell: vscode.NotebookCell): vscode.NotebookCellExecution {
|
||||||
|
return new ADSNotebookCellExecution(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
public dispose(): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateNotebookAffinity(notebook: vscode.NotebookDocument, affinity: vscode.NotebookControllerAffinity): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
public postMessage(message: any, editor?: vscode.NotebookEditor): Thenable<boolean> {
|
||||||
|
return Promise.resolve(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public asWebviewUri(localResource: vscode.Uri): vscode.Uri {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ADSNotebookCellExecution implements vscode.NotebookCellExecution {
|
||||||
|
private _executionOrder: number;
|
||||||
|
constructor(private readonly _cell: vscode.NotebookCell) {
|
||||||
|
this._executionOrder = this._cell.executionSummary?.executionOrder ?? -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get cell(): vscode.NotebookCell {
|
||||||
|
return this._cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get token(): vscode.CancellationToken {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get executionOrder(): number {
|
||||||
|
return this._executionOrder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set executionOrder(order: number) {
|
||||||
|
this._executionOrder = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public start(startTime?: number): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
public end(success: boolean, endTime?: number): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
public async clearOutput(cell?: vscode.NotebookCell): Promise<void> {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
public async replaceOutput(out: vscode.NotebookCellOutput | vscode.NotebookCellOutput[], cell?: vscode.NotebookCell): Promise<void> {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
public async appendOutput(out: vscode.NotebookCellOutput | vscode.NotebookCellOutput[], cell?: vscode.NotebookCell): Promise<void> {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
public async replaceOutputItems(items: vscode.NotebookCellOutputItem | vscode.NotebookCellOutputItem[], output: vscode.NotebookCellOutput): Promise<void> {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
public async appendOutputItems(items: vscode.NotebookCellOutputItem | vscode.NotebookCellOutputItem[], output: vscode.NotebookCellOutput): Promise<void> {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,8 +3,8 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import type * as azdata from 'azdata';
|
||||||
import * as vscode from 'vscode';
|
import type * as vscode from 'vscode';
|
||||||
|
|
||||||
import { IMainContext } from 'vs/workbench/api/common/extHost.protocol';
|
import { IMainContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||||
import { Disposable } from 'vs/workbench/api/common/extHostTypes';
|
import { Disposable } from 'vs/workbench/api/common/extHostTypes';
|
||||||
@@ -13,6 +13,10 @@ import { URI, UriComponents } from 'vs/base/common/uri';
|
|||||||
|
|
||||||
import { ExtHostNotebookShape, MainThreadNotebookShape, SqlMainContext } from 'sql/workbench/api/common/sqlExtHost.protocol';
|
import { ExtHostNotebookShape, MainThreadNotebookShape, SqlMainContext } from 'sql/workbench/api/common/sqlExtHost.protocol';
|
||||||
import { IExecuteManagerDetails, INotebookSessionDetails, INotebookKernelDetails, INotebookFutureDetails, FutureMessageType, ISerializationManagerDetails } from 'sql/workbench/api/common/sqlExtHostTypes';
|
import { IExecuteManagerDetails, INotebookSessionDetails, INotebookKernelDetails, INotebookFutureDetails, FutureMessageType, ISerializationManagerDetails } from 'sql/workbench/api/common/sqlExtHostTypes';
|
||||||
|
import { VSCodeSerializationProvider } from 'sql/workbench/api/common/vscodeSerializationProvider';
|
||||||
|
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||||
|
import { ADSNotebookController } from 'sql/workbench/api/common/adsNotebookController';
|
||||||
|
import { VSCodeExecuteProvider } from 'sql/workbench/api/common/vscodeExecuteProvider';
|
||||||
|
|
||||||
type Adapter = azdata.nb.NotebookSerializationProvider | azdata.nb.SerializationManager | azdata.nb.NotebookExecuteProvider | azdata.nb.ExecuteManager | azdata.nb.ISession | azdata.nb.IKernel | azdata.nb.IFuture;
|
type Adapter = azdata.nb.NotebookSerializationProvider | azdata.nb.SerializationManager | azdata.nb.NotebookExecuteProvider | azdata.nb.ExecuteManager | azdata.nb.ISession | azdata.nb.IKernel | azdata.nb.IFuture;
|
||||||
|
|
||||||
@@ -232,7 +236,6 @@ export class ExtHostNotebook implements ExtHostNotebookShape {
|
|||||||
return sessionManager.dispose();
|
return sessionManager.dispose();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region APIs called by extensions
|
//#region APIs called by extensions
|
||||||
@@ -253,11 +256,22 @@ export class ExtHostNotebook implements ExtHostNotebookShape {
|
|||||||
this._proxy.$registerSerializationProvider(provider.providerId, handle);
|
this._proxy.$registerSerializationProvider(provider.providerId, handle);
|
||||||
return this._createDisposable(handle);
|
return this._createDisposable(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerNotebookSerializer(notebookType: string, serializer: vscode.NotebookSerializer, options?: vscode.NotebookDocumentContentOptions, registration?: vscode.NotebookRegistrationData): vscode.Disposable {
|
||||||
|
let serializationProvider = new VSCodeSerializationProvider(notebookType, serializer);
|
||||||
|
return this.registerSerializationProvider(serializationProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
createNotebookController(extension: IExtensionDescription, id: string, viewType: string, label: string, handler?: (cells: vscode.NotebookCell[], notebook: vscode.NotebookDocument, controller: vscode.NotebookController) => void | Thenable<void>, rendererScripts?: vscode.NotebookRendererScript[]): vscode.NotebookController {
|
||||||
|
let addLanguagesHandler = (id, languages) => this._proxy.$updateProviderDescriptionLanguages(id, languages);
|
||||||
|
let controller = new ADSNotebookController(extension, id, viewType, label, addLanguagesHandler, handler, extension.enableProposedApi ? rendererScripts : undefined);
|
||||||
|
let executeProvider = new VSCodeExecuteProvider(controller);
|
||||||
|
this.registerExecuteProvider(executeProvider);
|
||||||
|
return controller;
|
||||||
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
|
||||||
//#region private methods
|
//#region private methods
|
||||||
|
|
||||||
private getAdapters<A>(ctor: { new(...args: any[]): A }): A[] {
|
private getAdapters<A>(ctor: { new(...args: any[]): A }): A[] {
|
||||||
let matchingAdapters = [];
|
let matchingAdapters = [];
|
||||||
this._adapters.forEach(a => {
|
this._adapters.forEach(a => {
|
||||||
|
|||||||
@@ -48,24 +48,20 @@ export interface IExtensionApiFactory {
|
|||||||
|
|
||||||
export interface IAdsExtensionApiFactory {
|
export interface IAdsExtensionApiFactory {
|
||||||
azdata: IAzdataExtensionApiFactory;
|
azdata: IAzdataExtensionApiFactory;
|
||||||
|
extHostNotebook: ExtHostNotebook;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method instantiates and returns the extension API surface
|
* This method instantiates and returns the extension API surface
|
||||||
*/
|
*/
|
||||||
export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): IExtensionApiFactory {
|
export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): IExtensionApiFactory {
|
||||||
const { azdata } = createAdsApiFactory(accessor);
|
const { azdata, extHostNotebook } = createAdsApiFactory(accessor);
|
||||||
return {
|
return {
|
||||||
azdata,
|
azdata,
|
||||||
vscode: vsApiFactory(accessor)
|
vscode: vsApiFactory(accessor, extHostNotebook)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface IAdsExtensionApiFactory {
|
|
||||||
azdata: IAzdataExtensionApiFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method instantiates and returns the extension API surface
|
* This method instantiates and returns the extension API surface
|
||||||
*/
|
*/
|
||||||
@@ -634,6 +630,7 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp
|
|||||||
TextType: sqlExtHostTypes.TextType,
|
TextType: sqlExtHostTypes.TextType,
|
||||||
designers: designers
|
designers: designers
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
|
extHostNotebook: extHostNotebook
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import { URI, UriComponents } from 'vs/base/common/uri';
|
|||||||
|
|
||||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||||
|
|
||||||
import * as azdata from 'azdata';
|
import type * as azdata from 'azdata';
|
||||||
import * as vscode from 'vscode';
|
import type * as vscode from 'vscode';
|
||||||
|
|
||||||
import { ITreeComponentItem } from 'sql/workbench/common/views';
|
import { ITreeComponentItem } from 'sql/workbench/common/views';
|
||||||
import { ITaskHandlerDescription } from 'sql/workbench/services/tasks/common/tasks';
|
import { ITaskHandlerDescription } from 'sql/workbench/services/tasks/common/tasks';
|
||||||
@@ -887,7 +887,6 @@ export interface MainThreadQueryEditorShape extends IDisposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ExtHostNotebookShape {
|
export interface ExtHostNotebookShape {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up a notebook manager for a given notebook URI
|
* Looks up a notebook manager for a given notebook URI
|
||||||
* @returns handle of the manager to be used when sending
|
* @returns handle of the manager to be used when sending
|
||||||
@@ -935,6 +934,7 @@ export interface MainThreadNotebookShape extends IDisposable {
|
|||||||
$unregisterExecuteProvider(handle: number): void;
|
$unregisterExecuteProvider(handle: number): void;
|
||||||
$onFutureMessage(futureId: number, type: FutureMessageType, payload: azdata.nb.IMessage): void;
|
$onFutureMessage(futureId: number, type: FutureMessageType, payload: azdata.nb.IMessage): void;
|
||||||
$onFutureDone(futureId: number, done: INotebookFutureDone): void;
|
$onFutureDone(futureId: number, done: INotebookFutureDone): void;
|
||||||
|
$updateProviderDescriptionLanguages(providerId: string, languages: string[]): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface INotebookDocumentsAndEditorsDelta {
|
export interface INotebookDocumentsAndEditorsDelta {
|
||||||
|
|||||||
@@ -0,0 +1,316 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import type * as vscode from 'vscode';
|
||||||
|
import type * as azdata from 'azdata';
|
||||||
|
import { ADSNotebookController } from 'sql/workbench/api/common/adsNotebookController';
|
||||||
|
import * as nls from 'vs/nls';
|
||||||
|
|
||||||
|
class VSCodeFuture implements azdata.nb.IFuture {
|
||||||
|
private _inProgress = true;
|
||||||
|
|
||||||
|
constructor(private readonly _executeCompletion: Promise<void>) {
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose() {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
public get inProgress(): boolean {
|
||||||
|
return this._inProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set inProgress(value: boolean) {
|
||||||
|
this._inProgress = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get msg(): azdata.nb.IMessage | undefined {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get done(): Thenable<azdata.nb.IShellMessage | undefined> {
|
||||||
|
return this._executeCompletion.then(() => {
|
||||||
|
return undefined;
|
||||||
|
}).finally(() => {
|
||||||
|
this._inProgress = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setReplyHandler(handler: azdata.nb.MessageHandler<azdata.nb.IShellMessage>): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
setStdInHandler(handler: azdata.nb.MessageHandler<azdata.nb.IStdinMessage>): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
setIOPubHandler(handler: azdata.nb.MessageHandler<azdata.nb.IIOPubMessage>): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
registerMessageHook(hook: (msg: azdata.nb.IIOPubMessage) => boolean | Thenable<boolean>): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
removeMessageHook(hook: (msg: azdata.nb.IIOPubMessage) => boolean | Thenable<boolean>): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
sendInputReply(content: azdata.nb.IInputReply): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VSCodeKernel implements azdata.nb.IKernel {
|
||||||
|
protected static kernelId = 0;
|
||||||
|
private readonly _id: string;
|
||||||
|
private readonly _name: string;
|
||||||
|
private readonly _info: azdata.nb.IInfoReply;
|
||||||
|
private readonly _kernelSpec: azdata.nb.IKernelSpec;
|
||||||
|
|
||||||
|
constructor(private readonly _controller: ADSNotebookController, private readonly _options: azdata.nb.ISessionOptions, language: string) {
|
||||||
|
this._id = this._options.kernelId ?? (VSCodeKernel.kernelId++).toString();
|
||||||
|
this._name = this._options.kernelName ?? this._controller.notebookType;
|
||||||
|
this._info = {
|
||||||
|
protocol_version: '',
|
||||||
|
implementation: '',
|
||||||
|
implementation_version: '',
|
||||||
|
language_info: {
|
||||||
|
name: language,
|
||||||
|
version: '',
|
||||||
|
},
|
||||||
|
banner: '',
|
||||||
|
help_links: [{
|
||||||
|
text: '',
|
||||||
|
url: ''
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
this._kernelSpec = {
|
||||||
|
name: this._name,
|
||||||
|
language: language,
|
||||||
|
display_name: this._name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public get id(): string {
|
||||||
|
return this._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get name(): string {
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get supportsIntellisense(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get requiresConnection(): boolean | undefined {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isReady(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get ready(): Thenable<void> {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get info(): azdata.nb.IInfoReply | null {
|
||||||
|
return this._info;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSpec(): Thenable<azdata.nb.IKernelSpec> {
|
||||||
|
return Promise.resolve(this._kernelSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestExecute(content: azdata.nb.IExecuteRequest, disposeOnDone?: boolean): azdata.nb.IFuture {
|
||||||
|
let executePromise: Promise<void>;
|
||||||
|
if (this._controller.executeHandler) {
|
||||||
|
let cell = <vscode.NotebookCell>{
|
||||||
|
document: <vscode.TextDocument>{
|
||||||
|
uri: content.notebookUri,
|
||||||
|
languageId: this._kernelSpec.language,
|
||||||
|
getText: () => Array.isArray(content.code) ? content.code.join('') : content.code,
|
||||||
|
},
|
||||||
|
notebook: <vscode.NotebookDocument>{
|
||||||
|
uri: content.notebookUri
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
executePromise = Promise.resolve(this._controller.executeHandler([cell], cell.notebook, this._controller));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
executePromise = Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VSCodeFuture(executePromise);
|
||||||
|
}
|
||||||
|
|
||||||
|
requestComplete(content: azdata.nb.ICompleteRequest): Thenable<azdata.nb.ICompleteReplyMsg> {
|
||||||
|
let response: Partial<azdata.nb.ICompleteReplyMsg> = {};
|
||||||
|
return Promise.resolve(response as azdata.nb.ICompleteReplyMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async interrupt(): Promise<void> {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VSCodeSession implements azdata.nb.ISession {
|
||||||
|
private _kernel: VSCodeKernel;
|
||||||
|
private _defaultKernelLoaded = false;
|
||||||
|
constructor(controller: ADSNotebookController, private readonly _options: azdata.nb.ISessionOptions, language: string) {
|
||||||
|
this._kernel = new VSCodeKernel(controller, this._options, language);
|
||||||
|
}
|
||||||
|
|
||||||
|
public set defaultKernelLoaded(value) {
|
||||||
|
this._defaultKernelLoaded = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get defaultKernelLoaded(): boolean {
|
||||||
|
return this._defaultKernelLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get canChangeKernels(): boolean {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get id(): string {
|
||||||
|
return this._options.kernelId || this._kernel ? this._kernel.id : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public get path(): string {
|
||||||
|
return this._options.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get name(): string {
|
||||||
|
return this._options.name || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public get type(): string {
|
||||||
|
return this._options.type || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
public get status(): azdata.nb.KernelStatus {
|
||||||
|
return 'connected';
|
||||||
|
}
|
||||||
|
|
||||||
|
public get kernel(): azdata.nb.IKernel {
|
||||||
|
return this._kernel;
|
||||||
|
}
|
||||||
|
|
||||||
|
changeKernel(kernelInfo: azdata.nb.IKernelSpec): Thenable<azdata.nb.IKernel> {
|
||||||
|
return Promise.resolve(this._kernel);
|
||||||
|
}
|
||||||
|
|
||||||
|
configureKernel(kernelInfo: azdata.nb.IKernelSpec): Thenable<void> {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
configureConnection(connection: azdata.IConnectionProfile): Thenable<void> {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VSCodeSessionManager implements azdata.nb.SessionManager {
|
||||||
|
private _sessions: azdata.nb.ISession[] = [];
|
||||||
|
|
||||||
|
constructor(private readonly _controller: ADSNotebookController) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isReady(): boolean {
|
||||||
|
return this._controller.supportedLanguages?.length > 0 && this._controller.executeHandler !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get ready(): Thenable<void> {
|
||||||
|
return Promise.all([this._controller.languagesAdded, this._controller.executionHandlerAdded]).then();
|
||||||
|
}
|
||||||
|
|
||||||
|
public get specs(): azdata.nb.IAllKernels {
|
||||||
|
let languages = this._controller.supportedLanguages?.length > 0 ? this._controller.supportedLanguages : [this._controller.label];
|
||||||
|
return {
|
||||||
|
defaultKernel: languages[0],
|
||||||
|
kernels: languages.map<azdata.nb.IKernelSpec>(language => {
|
||||||
|
return {
|
||||||
|
name: language,
|
||||||
|
language: language,
|
||||||
|
display_name: language
|
||||||
|
};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async startNew(options: azdata.nb.ISessionOptions): Promise<azdata.nb.ISession> {
|
||||||
|
if (!this.isReady) {
|
||||||
|
return Promise.reject(new Error(nls.localize('errorStartBeforeReady', "Cannot start a session, the manager is not yet initialized")));
|
||||||
|
}
|
||||||
|
|
||||||
|
let session: azdata.nb.ISession = new VSCodeSession(this._controller, options, this.specs.defaultKernel);
|
||||||
|
let index = this._sessions.findIndex(session => session.path === options.path);
|
||||||
|
if (index > -1) {
|
||||||
|
this._sessions.splice(index);
|
||||||
|
}
|
||||||
|
this._sessions.push(session);
|
||||||
|
return Promise.resolve(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
public shutdown(id: string): Thenable<void> {
|
||||||
|
let index = this._sessions.findIndex(session => session.id === id);
|
||||||
|
if (index > -1) {
|
||||||
|
this._sessions.splice(index);
|
||||||
|
}
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
public shutdownAll(): Thenable<void> {
|
||||||
|
return Promise.all(this._sessions.map(session => {
|
||||||
|
return this.shutdown(session.id);
|
||||||
|
})).then();
|
||||||
|
}
|
||||||
|
|
||||||
|
public dispose(): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VSCodeExecuteManager implements azdata.nb.ExecuteManager {
|
||||||
|
public readonly providerId: string;
|
||||||
|
private readonly _sessionManager: azdata.nb.SessionManager;
|
||||||
|
|
||||||
|
constructor(controller: ADSNotebookController) {
|
||||||
|
this.providerId = controller.notebookType;
|
||||||
|
this._sessionManager = new VSCodeSessionManager(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get sessionManager(): azdata.nb.SessionManager {
|
||||||
|
return this._sessionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get serverManager(): azdata.nb.ServerManager | undefined {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Notebook Execute Provider that is used to convert VS Code notebook extension APIs into ADS equivalents.
|
||||||
|
*/
|
||||||
|
export class VSCodeExecuteProvider implements azdata.nb.NotebookExecuteProvider {
|
||||||
|
public readonly providerId: string;
|
||||||
|
private readonly _executeManager: azdata.nb.ExecuteManager;
|
||||||
|
|
||||||
|
constructor(controller: ADSNotebookController) {
|
||||||
|
this._executeManager = new VSCodeExecuteManager(controller);
|
||||||
|
this.providerId = controller.notebookType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getExecuteManager(notebookUri: vscode.Uri): Thenable<azdata.nb.ExecuteManager> {
|
||||||
|
return Promise.resolve(this._executeManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
public handleNotebookClosed(notebookUri: vscode.Uri): void {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import type * as vscode from 'vscode';
|
||||||
|
import type * as azdata from 'azdata';
|
||||||
|
import { VSBuffer } from 'vs/base/common/buffer';
|
||||||
|
import { NotebookCellKind } from 'vs/workbench/api/common/extHostTypes';
|
||||||
|
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||||
|
import { OutputTypes } from 'sql/workbench/services/notebook/common/contracts';
|
||||||
|
import { NBFORMAT, NBFORMAT_MINOR } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Notebook Content Manager that is used as part of converting VS Code notebook extension APIs into ADS equivalents.
|
||||||
|
*/
|
||||||
|
export class VSCodeContentManager implements azdata.nb.ContentManager {
|
||||||
|
constructor(private readonly _serializer: vscode.NotebookSerializer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static convertToADSCellOutput(output: vscode.NotebookCellOutput, executionOrder?: number): azdata.nb.IExecuteResult {
|
||||||
|
let outputData = {};
|
||||||
|
for (let item of output.items) {
|
||||||
|
outputData[item.mime] = VSBuffer.wrap(item.data).toString();
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
output_type: 'execute_result',
|
||||||
|
data: outputData,
|
||||||
|
execution_count: executionOrder,
|
||||||
|
metadata: output.metadata,
|
||||||
|
id: output.id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async deserializeNotebook(contents: string): Promise<azdata.nb.INotebookContents> {
|
||||||
|
let buffer = VSBuffer.fromString(contents);
|
||||||
|
let notebookData = await this._serializer.deserializeNotebook(buffer.buffer, new CancellationTokenSource().token);
|
||||||
|
let result = {
|
||||||
|
cells: notebookData.cells?.map<azdata.nb.ICellContents>(cell => {
|
||||||
|
let executionOrder = cell.executionSummary?.executionOrder;
|
||||||
|
return {
|
||||||
|
cell_type: cell.kind === NotebookCellKind.Code ? 'code' : 'markdown',
|
||||||
|
source: cell.value,
|
||||||
|
metadata: {
|
||||||
|
language: cell.languageId
|
||||||
|
},
|
||||||
|
execution_count: executionOrder,
|
||||||
|
outputs: cell.outputs?.map<azdata.nb.IExecuteResult>(output => VSCodeContentManager.convertToADSCellOutput(output, executionOrder))
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
metadata: notebookData.metadata ?? {},
|
||||||
|
nbformat: notebookData.metadata?.custom?.nbformat ?? NBFORMAT,
|
||||||
|
nbformat_minor: notebookData.metadata?.custom?.nbformat_minor ?? NBFORMAT_MINOR
|
||||||
|
};
|
||||||
|
|
||||||
|
// Clear out extra lingering vscode custom metadata
|
||||||
|
delete result.metadata.custom;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static convertToVSCodeCellOutput(output: azdata.nb.ICellOutput): vscode.NotebookCellOutput {
|
||||||
|
let convertedOutputItems: vscode.NotebookCellOutputItem[];
|
||||||
|
switch (output.output_type) {
|
||||||
|
case OutputTypes.ExecuteResult:
|
||||||
|
case OutputTypes.DisplayData:
|
||||||
|
case OutputTypes.UpdateDisplayData:
|
||||||
|
let displayOutput = output as azdata.nb.IDisplayResult;
|
||||||
|
convertedOutputItems = Object.keys(displayOutput.data).map<vscode.NotebookCellOutputItem>(key => {
|
||||||
|
return {
|
||||||
|
mime: key,
|
||||||
|
data: VSBuffer.fromString(displayOutput.data[key]).buffer
|
||||||
|
};
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case OutputTypes.Stream:
|
||||||
|
let streamOutput = output as azdata.nb.IStreamResult;
|
||||||
|
convertedOutputItems = [{
|
||||||
|
mime: 'text/html',
|
||||||
|
data: VSBuffer.fromString(Array.isArray(streamOutput.text) ? streamOutput.text.join('') : streamOutput.text).buffer
|
||||||
|
}];
|
||||||
|
break;
|
||||||
|
case OutputTypes.Error:
|
||||||
|
let errorOutput = output as azdata.nb.IErrorResult;
|
||||||
|
let errorString = errorOutput.ename + ': ' + errorOutput.evalue + (errorOutput.traceback ? '\n' + errorOutput.traceback?.join('\n') : '');
|
||||||
|
convertedOutputItems = [{
|
||||||
|
mime: 'text/html',
|
||||||
|
data: VSBuffer.fromString(errorString).buffer
|
||||||
|
}];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
items: convertedOutputItems,
|
||||||
|
metadata: output.metadata,
|
||||||
|
id: output.id
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public async serializeNotebook(notebook: azdata.nb.INotebookContents): Promise<string> {
|
||||||
|
let notebookData: vscode.NotebookData = {
|
||||||
|
cells: notebook.cells?.map<vscode.NotebookCellData>(cell => {
|
||||||
|
return {
|
||||||
|
kind: cell.cell_type === 'code' ? NotebookCellKind.Code : NotebookCellKind.Markup,
|
||||||
|
value: Array.isArray(cell.source) ? cell.source.join('\n') : cell.source,
|
||||||
|
languageId: cell.metadata?.language,
|
||||||
|
outputs: cell.outputs?.map<vscode.NotebookCellOutput>(output => VSCodeContentManager.convertToVSCodeCellOutput(output)),
|
||||||
|
executionSummary: {
|
||||||
|
executionOrder: cell.execution_count
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
metadata: notebook.metadata
|
||||||
|
};
|
||||||
|
notebookData.metadata.custom = {
|
||||||
|
nbformat: notebook.nbformat,
|
||||||
|
nbformat_minor: notebook.nbformat_minor
|
||||||
|
};
|
||||||
|
|
||||||
|
let bytes = await this._serializer.serializeNotebook(notebookData, new CancellationTokenSource().token);
|
||||||
|
let buffer = VSBuffer.wrap(bytes);
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class VSCodeSerializationManager implements azdata.nb.SerializationManager {
|
||||||
|
private _manager: VSCodeContentManager;
|
||||||
|
|
||||||
|
constructor(serializer: vscode.NotebookSerializer) {
|
||||||
|
this._manager = new VSCodeContentManager(serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get contentManager(): azdata.nb.ContentManager {
|
||||||
|
return this._manager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Notebook Serialization Provider that is used to convert VS Code notebook extension APIs into ADS equivalents.
|
||||||
|
*/
|
||||||
|
export class VSCodeSerializationProvider implements azdata.nb.NotebookSerializationProvider {
|
||||||
|
private _manager: VSCodeSerializationManager;
|
||||||
|
|
||||||
|
constructor(public readonly providerId: string, serializer: vscode.NotebookSerializer) {
|
||||||
|
this._manager = new VSCodeSerializationManager(serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSerializationManager(notebookUri: vscode.Uri): Thenable<azdata.nb.SerializationManager> {
|
||||||
|
return Promise.resolve(this._manager);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,6 +37,10 @@ export const RESOURCE_VIEWER_TYPEID = 'workbench.editorInput.resourceViewerInput
|
|||||||
|
|
||||||
export const JUPYTER_PROVIDER_ID = 'jupyter';
|
export const JUPYTER_PROVIDER_ID = 'jupyter';
|
||||||
|
|
||||||
|
// The version of the notebook file format that we support
|
||||||
|
export const NBFORMAT = 4;
|
||||||
|
export const NBFORMAT_MINOR = 2;
|
||||||
|
|
||||||
export const enum NotebookLanguage {
|
export const enum NotebookLanguage {
|
||||||
Notebook = 'Notebook',
|
Notebook = 'Notebook',
|
||||||
Ipynb = 'ipynb'
|
Ipynb = 'ipynb'
|
||||||
|
|||||||
@@ -444,10 +444,10 @@ export abstract class NotebookInput extends EditorInput implements INotebookInpu
|
|||||||
this._providerId = providerIds.filter(provider => provider !== DEFAULT_NOTEBOOK_PROVIDER)[0];
|
this._providerId = providerIds.filter(provider => provider !== DEFAULT_NOTEBOOK_PROVIDER)[0];
|
||||||
this._providers = providerIds;
|
this._providers = providerIds;
|
||||||
this._standardKernels = [];
|
this._standardKernels = [];
|
||||||
this._providers.forEach(provider => {
|
for (let provider of this._providers) {
|
||||||
let standardKernels = getStandardKernelsForProvider(provider, this.notebookService);
|
let standardKernels = await getStandardKernelsForProvider(provider, this.notebookService);
|
||||||
this._standardKernels.push(...standardKernels);
|
this._standardKernels.push(...standardKernels);
|
||||||
});
|
}
|
||||||
let serializationProvider = await this.notebookService.getOrCreateSerializationManager(this._providerId, this._resource);
|
let serializationProvider = await this.notebookService.getOrCreateSerializationManager(this._providerId, this._resource);
|
||||||
this._contentLoader = this.instantiationService.createInstance(NotebookEditorContentLoader, this, serializationProvider.contentManager);
|
this._contentLoader = this.instantiationService.createInstance(NotebookEditorContentLoader, this, serializationProvider.contentManager);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
|
|||||||
import { ExecuteManagerStub, SerializationManagerStub } from 'sql/workbench/contrib/notebook/test/stubs';
|
import { ExecuteManagerStub, SerializationManagerStub } from 'sql/workbench/contrib/notebook/test/stubs';
|
||||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
|
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
|
||||||
|
import { NBFORMAT, NBFORMAT_MINOR } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
suite('CellToolbarActions', function (): void {
|
suite('CellToolbarActions', function (): void {
|
||||||
suite('removeDuplicatedAndStartingSeparators', function (): void {
|
suite('removeDuplicatedAndStartingSeparators', function (): void {
|
||||||
@@ -211,8 +212,8 @@ export async function createandLoadNotebookModel(codeContent?: nb.INotebookConte
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let serviceCollection = new ServiceCollection();
|
let serviceCollection = new ServiceCollection();
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import { Separator } from 'vs/base/common/actions';
|
|||||||
import { INotebookView, INotebookViews } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViews';
|
import { INotebookView, INotebookViews } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViews';
|
||||||
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
|
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
|
||||||
import { ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry';
|
import { ITelemetryEventProperties } from 'sql/platform/telemetry/common/telemetry';
|
||||||
|
import { NBFORMAT, NBFORMAT_MINOR } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
class TestClientSession extends ClientSessionStub {
|
class TestClientSession extends ClientSessionStub {
|
||||||
private _errorState: boolean = false;
|
private _errorState: boolean = false;
|
||||||
@@ -280,8 +281,8 @@ suite('Notebook Actions', function (): void {
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let mockNotification = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService);
|
let mockNotification = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService);
|
||||||
@@ -324,8 +325,8 @@ suite('Notebook Actions', function (): void {
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let expectedMsg: string = noParameterCell;
|
let expectedMsg: string = noParameterCell;
|
||||||
|
|
||||||
@@ -365,8 +366,8 @@ suite('Notebook Actions', function (): void {
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let expectedMsg: string = noParametersInCell;
|
let expectedMsg: string = noParametersInCell;
|
||||||
|
|
||||||
@@ -410,8 +411,8 @@ suite('Notebook Actions', function (): void {
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let expectedMsg: string = noParametersInCell;
|
let expectedMsg: string = noParametersInCell;
|
||||||
|
|
||||||
@@ -456,8 +457,8 @@ suite('Notebook Actions', function (): void {
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let expectedMsg: string = noParametersInCell;
|
let expectedMsg: string = noParametersInCell;
|
||||||
|
|
||||||
@@ -505,8 +506,8 @@ suite('Notebook Actions', function (): void {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let expectedMsg: string = kernelNotSupported;
|
let expectedMsg: string = kernelNotSupported;
|
||||||
|
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ suite('Notebook Input', function (): void {
|
|||||||
const mockNotebookService = TypeMoq.Mock.ofType<INotebookService>(NotebookServiceStub);
|
const mockNotebookService = TypeMoq.Mock.ofType<INotebookService>(NotebookServiceStub);
|
||||||
mockNotebookService.setup(s => s.getProvidersForFileType(TypeMoq.It.isAny())).returns(() => [testProvider]);
|
mockNotebookService.setup(s => s.getProvidersForFileType(TypeMoq.It.isAny())).returns(() => [testProvider]);
|
||||||
mockNotebookService.setup(s => s.getStandardKernelsForProvider(TypeMoq.It.isAny())).returns(() => {
|
mockNotebookService.setup(s => s.getStandardKernelsForProvider(TypeMoq.It.isAny())).returns(() => {
|
||||||
return [{
|
return Promise.resolve([{
|
||||||
name: 'TestName',
|
name: 'TestName',
|
||||||
displayName: 'TestDisplayName',
|
displayName: 'TestDisplayName',
|
||||||
connectionProviderIds: ['TestId'],
|
connectionProviderIds: ['TestId'],
|
||||||
notebookProvider: testProvider
|
notebookProvider: testProvider
|
||||||
}];
|
}]);
|
||||||
});
|
});
|
||||||
let testManager: ISerializationManager = {
|
let testManager: ISerializationManager = {
|
||||||
providerId: testProvider,
|
providerId: testProvider,
|
||||||
|
|||||||
@@ -222,7 +222,8 @@ suite.skip('NotebookService:', function (): void {
|
|||||||
assert.strictEqual(notebookService.listNotebookEditors().length, 0, 'No notebook editors should be listed');
|
assert.strictEqual(notebookService.listNotebookEditors().length, 0, 'No notebook editors should be listed');
|
||||||
assert.strictEqual(notebookService.getMimeRegistry().mimeTypes.length, 15, 'MIME Types need to have appropriate tests when added or removed');
|
assert.strictEqual(notebookService.getMimeRegistry().mimeTypes.length, 15, 'MIME Types need to have appropriate tests when added or removed');
|
||||||
assert.deepStrictEqual(notebookService.getProvidersForFileType('.ipynb'), ['sql'], 'sql provider should be registered for ipynb extension');
|
assert.deepStrictEqual(notebookService.getProvidersForFileType('.ipynb'), ['sql'], 'sql provider should be registered for ipynb extension');
|
||||||
assert.strictEqual(notebookService.getStandardKernelsForProvider('sql').length, 1, 'SQL kernel should be provided by default');
|
let standardKernels = await notebookService.getStandardKernelsForProvider('sql');
|
||||||
|
assert.strictEqual(standardKernels.length, 1, 'SQL kernel should be provided by default');
|
||||||
assert.strictEqual(notebookService.getStandardKernelsForProvider('otherProvider'), undefined, 'Other provider should not have kernels since it has not been added as a provider');
|
assert.strictEqual(notebookService.getStandardKernelsForProvider('otherProvider'), undefined, 'Other provider should not have kernels since it has not been added as a provider');
|
||||||
assert.deepStrictEqual(notebookService.getSupportedFileExtensions(), ['.ipynb'], 'IPYNB file extension should be supported by default');
|
assert.deepStrictEqual(notebookService.getSupportedFileExtensions(), ['.ipynb'], 'IPYNB file extension should be supported by default');
|
||||||
await notebookService.registrationComplete;
|
await notebookService.registrationComplete;
|
||||||
@@ -248,7 +249,8 @@ suite.skip('NotebookService:', function (): void {
|
|||||||
|
|
||||||
assert.deepStrictEqual(notebookService.getProvidersForFileType('.ipynb'), ['sql', 'otherProvider'], 'otherProvider should also be registered for ipynb extension');
|
assert.deepStrictEqual(notebookService.getProvidersForFileType('.ipynb'), ['sql', 'otherProvider'], 'otherProvider should also be registered for ipynb extension');
|
||||||
assert.deepStrictEqual(notebookService.getSupportedFileExtensions(), ['.ipynb'], 'Only IPYNB should be registered as supported file extension');
|
assert.deepStrictEqual(notebookService.getSupportedFileExtensions(), ['.ipynb'], 'Only IPYNB should be registered as supported file extension');
|
||||||
assert.strictEqual(notebookService.getStandardKernelsForProvider('otherProvider').length, 1, 'otherProvider kernel info could not be found');
|
let standardKernels = await notebookService.getStandardKernelsForProvider('otherProvider');
|
||||||
|
assert.strictEqual(standardKernels.length, 1, 'otherProvider kernel info could not be found');
|
||||||
assert.deepStrictEqual(notebookService.getStandardKernelsForProvider('otherProvider')[0], otherProviderRegistration.standardKernels[0], 'otherProviderRegistration standard kernels does not match');
|
assert.deepStrictEqual(notebookService.getStandardKernelsForProvider('otherProvider')[0], otherProviderRegistration.standardKernels[0], 'otherProviderRegistration standard kernels does not match');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -557,7 +559,7 @@ suite.skip('NotebookService:', function (): void {
|
|||||||
await notebookService.registrationComplete;
|
await notebookService.registrationComplete;
|
||||||
queryManagementService.onHandlerAddedEmitter.fire(SQL_NOTEBOOK_PROVIDER);
|
queryManagementService.onHandlerAddedEmitter.fire(SQL_NOTEBOOK_PROVIDER);
|
||||||
const connectionTypes = queryManagementService.getRegisteredProviders();
|
const connectionTypes = queryManagementService.getRegisteredProviders();
|
||||||
const kernels = notebookService.getStandardKernelsForProvider(SQL_NOTEBOOK_PROVIDER);
|
const kernels = await notebookService.getStandardKernelsForProvider(SQL_NOTEBOOK_PROVIDER);
|
||||||
for (const kernel of kernels) {
|
for (const kernel of kernels) {
|
||||||
assert.strictEqual(kernel.name, notebookConstants.SQL, `kernel name for standard kernels should be ${notebookConstants.SQL}`);
|
assert.strictEqual(kernel.name, notebookConstants.SQL, `kernel name for standard kernels should be ${notebookConstants.SQL}`);
|
||||||
assert.strictEqual(kernel.displayName, notebookConstants.SQL, `kernel displayName for standard kernels should be ${notebookConstants.SQL}`);
|
assert.strictEqual(kernel.displayName, notebookConstants.SQL, `kernel displayName for standard kernels should be ${notebookConstants.SQL}`);
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ import { TestConfigurationService } from 'sql/platform/connection/test/common/te
|
|||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { NotebookViewModel } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViewModel';
|
import { NotebookViewModel } from 'sql/workbench/services/notebook/browser/notebookViews/notebookViewModel';
|
||||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||||
|
import { SQL_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/browser/notebookService';
|
||||||
|
import { NBFORMAT, NBFORMAT_MINOR } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
let initialNotebookContent: nb.INotebookContents = {
|
let initialNotebookContent: nb.INotebookContents = {
|
||||||
cells: [{
|
cells: [{
|
||||||
@@ -52,8 +54,8 @@ let initialNotebookContent: nb.INotebookContents = {
|
|||||||
language: 'sql'
|
language: 'sql'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let notebookContentWithoutMeta: nb.INotebookContents = {
|
let notebookContentWithoutMeta: nb.INotebookContents = {
|
||||||
@@ -67,8 +69,8 @@ let notebookContentWithoutMeta: nb.INotebookContents = {
|
|||||||
execution_count: 1
|
execution_count: 1
|
||||||
}],
|
}],
|
||||||
metadata: {},
|
metadata: {},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let defaultUri = URI.file('/some/path.ipynb');
|
let defaultUri = URI.file('/some/path.ipynb');
|
||||||
@@ -240,6 +242,7 @@ suite('NotebookViewModel', function (): void {
|
|||||||
|
|
||||||
function setupServices() {
|
function setupServices() {
|
||||||
mockSessionManager = TypeMoq.Mock.ofType(SessionManager);
|
mockSessionManager = TypeMoq.Mock.ofType(SessionManager);
|
||||||
|
executeManagers[0].providerId = SQL_NOTEBOOK_PROVIDER;
|
||||||
executeManagers[0].sessionManager = mockSessionManager.object;
|
executeManagers[0].sessionManager = mockSessionManager.object;
|
||||||
notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
|
notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
|
||||||
capabilitiesService = TypeMoq.Mock.ofType<ICapabilitiesService>(TestCapabilitiesService);
|
capabilitiesService = TypeMoq.Mock.ofType<ICapabilitiesService>(TestCapabilitiesService);
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServic
|
|||||||
import sinon = require('sinon');
|
import sinon = require('sinon');
|
||||||
import { InsertCellsModal } from 'sql/workbench/contrib/notebook/browser/notebookViews/insertCellsModal';
|
import { InsertCellsModal } from 'sql/workbench/contrib/notebook/browser/notebookViews/insertCellsModal';
|
||||||
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
|
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
|
||||||
|
import { SQL_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/browser/notebookService';
|
||||||
|
import { NBFORMAT, NBFORMAT_MINOR } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
let initialNotebookContent: nb.INotebookContents = {
|
let initialNotebookContent: nb.INotebookContents = {
|
||||||
cells: [{
|
cells: [{
|
||||||
@@ -52,8 +54,8 @@ let initialNotebookContent: nb.INotebookContents = {
|
|||||||
language: 'sql'
|
language: 'sql'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
suite('Notebook Views Actions', function (): void {
|
suite('Notebook Views Actions', function (): void {
|
||||||
@@ -165,6 +167,7 @@ suite('Notebook Views Actions', function (): void {
|
|||||||
|
|
||||||
function setupServices() {
|
function setupServices() {
|
||||||
mockSessionManager = TypeMoq.Mock.ofType(SessionManager);
|
mockSessionManager = TypeMoq.Mock.ofType(SessionManager);
|
||||||
|
executeManagers[0].providerId = SQL_NOTEBOOK_PROVIDER;
|
||||||
executeManagers[0].sessionManager = mockSessionManager.object;
|
executeManagers[0].sessionManager = mockSessionManager.object;
|
||||||
notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
|
notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
|
||||||
capabilitiesService = TypeMoq.Mock.ofType<ICapabilitiesService>(TestCapabilitiesService);
|
capabilitiesService = TypeMoq.Mock.ofType<ICapabilitiesService>(TestCapabilitiesService);
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogSer
|
|||||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
|
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
|
||||||
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
||||||
|
import { SQL_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/browser/notebookService';
|
||||||
|
import { NBFORMAT, NBFORMAT_MINOR } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
let initialNotebookContent: nb.INotebookContents = {
|
let initialNotebookContent: nb.INotebookContents = {
|
||||||
cells: [{
|
cells: [{
|
||||||
@@ -54,8 +56,8 @@ let initialNotebookContent: nb.INotebookContents = {
|
|||||||
language: 'sql'
|
language: 'sql'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let defaultUri = URI.file('/some/path.ipynb');
|
let defaultUri = URI.file('/some/path.ipynb');
|
||||||
@@ -151,6 +153,7 @@ suite('NotebookViews', function (): void {
|
|||||||
|
|
||||||
function setupServices() {
|
function setupServices() {
|
||||||
mockSessionManager = TypeMoq.Mock.ofType(SessionManager);
|
mockSessionManager = TypeMoq.Mock.ofType(SessionManager);
|
||||||
|
executeManagers[0].providerId = SQL_NOTEBOOK_PROVIDER;
|
||||||
executeManagers[0].sessionManager = mockSessionManager.object;
|
executeManagers[0].sessionManager = mockSessionManager.object;
|
||||||
notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
|
notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
|
||||||
capabilitiesService = TypeMoq.Mock.ofType<ICapabilitiesService>(TestCapabilitiesService);
|
capabilitiesService = TypeMoq.Mock.ofType<ICapabilitiesService>(TestCapabilitiesService);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { TestFileService } from 'vs/workbench/test/browser/workbenchTestServices
|
|||||||
import { IFileService, IReadFileOptions, IFileContent, IWriteFileOptions, IFileStatWithMetadata } from 'vs/platform/files/common/files';
|
import { IFileService, IReadFileOptions, IFileContent, IWriteFileOptions, IFileStatWithMetadata } from 'vs/platform/files/common/files';
|
||||||
import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer';
|
import { VSBuffer, VSBufferReadable } from 'vs/base/common/buffer';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
|
import { NBFORMAT, NBFORMAT_MINOR } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
let expectedNotebookContent: nb.INotebookContents = {
|
let expectedNotebookContent: nb.INotebookContents = {
|
||||||
cells: [{
|
cells: [{
|
||||||
@@ -32,8 +33,8 @@ let expectedNotebookContent: nb.INotebookContents = {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 2
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let notebookContentString = JSON.stringify(expectedNotebookContent);
|
let notebookContentString = JSON.stringify(expectedNotebookContent);
|
||||||
@@ -105,8 +106,8 @@ suite('Local Content Manager', function (): void {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 2
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let mimeContentString = JSON.stringify(mimeNotebook);
|
let mimeContentString = JSON.stringify(mimeNotebook);
|
||||||
// when I read the content
|
// when I read the content
|
||||||
@@ -155,8 +156,8 @@ suite('Local Content Manager', function (): void {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 2
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let markdownNotebookContent = JSON.stringify(expectedNotebookMarkdownContent);
|
let markdownNotebookContent = JSON.stringify(expectedNotebookMarkdownContent);
|
||||||
// verify that notebooks support markdown cells
|
// verify that notebooks support markdown cells
|
||||||
@@ -189,8 +190,8 @@ suite('Local Content Manager', function (): void {
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 2
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let streamOutputContent = JSON.stringify(expectedNotebookStreamOutputContent);
|
let streamOutputContent = JSON.stringify(expectedNotebookStreamOutputContent);
|
||||||
// Verify that the stream output type is supported
|
// Verify that the stream output type is supported
|
||||||
|
|||||||
+22
-17
@@ -27,11 +27,13 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia
|
|||||||
import { ClientSession } from 'sql/workbench/services/notebook/browser/models/clientSession';
|
import { ClientSession } from 'sql/workbench/services/notebook/browser/models/clientSession';
|
||||||
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
|
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
|
||||||
import { NotebookEditorContentLoader } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
|
import { NotebookEditorContentLoader } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
|
||||||
import { NotebookRange } from 'sql/workbench/services/notebook/browser/notebookService';
|
import { NotebookRange, SQL_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/browser/notebookService';
|
||||||
import { NotebookMarkdownRenderer } from 'sql/workbench/contrib/notebook/browser/outputs/notebookMarkdown';
|
import { NotebookMarkdownRenderer } from 'sql/workbench/contrib/notebook/browser/outputs/notebookMarkdown';
|
||||||
import { NullAdsTelemetryService } from 'sql/platform/telemetry/common/adsTelemetryService';
|
import { NullAdsTelemetryService } from 'sql/platform/telemetry/common/adsTelemetryService';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { TestConfigurationService } from 'sql/platform/connection/test/common/testConfigurationService';
|
import { TestConfigurationService } from 'sql/platform/connection/test/common/testConfigurationService';
|
||||||
|
import { SessionManager } from 'sql/workbench/contrib/notebook/test/emptySessionClasses';
|
||||||
|
import { NBFORMAT, NBFORMAT_MINOR } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
let expectedNotebookContent: nb.INotebookContents = {
|
let expectedNotebookContent: nb.INotebookContents = {
|
||||||
cells: [{
|
cells: [{
|
||||||
@@ -52,8 +54,8 @@ let expectedNotebookContent: nb.INotebookContents = {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let defaultUri = URI.file('/some/path.ipynb');
|
let defaultUri = URI.file('/some/path.ipynb');
|
||||||
@@ -78,6 +80,9 @@ suite('Notebook Find Model', function (): void {
|
|||||||
let configurationService: IConfigurationService;
|
let configurationService: IConfigurationService;
|
||||||
|
|
||||||
setup(async () => {
|
setup(async () => {
|
||||||
|
let mockSessionManager = TypeMoq.Mock.ofType(SessionManager);
|
||||||
|
executeManagers[0].providerId = SQL_NOTEBOOK_PROVIDER;
|
||||||
|
executeManagers[0].sessionManager = mockSessionManager.object;
|
||||||
sessionReady = new Deferred<void>();
|
sessionReady = new Deferred<void>();
|
||||||
notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
|
notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
|
||||||
capabilitiesService = TypeMoq.Mock.ofType<ICapabilitiesService>(TestCapabilitiesService);
|
capabilitiesService = TypeMoq.Mock.ofType<ICapabilitiesService>(TestCapabilitiesService);
|
||||||
@@ -195,8 +200,8 @@ suite('Notebook Find Model', function (): void {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
await initNotebookModel(markdownContent);
|
await initNotebookModel(markdownContent);
|
||||||
|
|
||||||
@@ -228,8 +233,8 @@ suite('Notebook Find Model', function (): void {
|
|||||||
display_name: 'Python'
|
display_name: 'Python'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
await initNotebookModel(codeContent);
|
await initNotebookModel(codeContent);
|
||||||
//initialize find
|
//initialize find
|
||||||
@@ -254,8 +259,8 @@ suite('Notebook Find Model', function (): void {
|
|||||||
display_name: 'Python'
|
display_name: 'Python'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
await initNotebookModel(codeContent);
|
await initNotebookModel(codeContent);
|
||||||
//initialize find
|
//initialize find
|
||||||
@@ -315,8 +320,8 @@ suite('Notebook Find Model', function (): void {
|
|||||||
display_name: 'Python'
|
display_name: 'Python'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
await initNotebookModel(codeContent);
|
await initNotebookModel(codeContent);
|
||||||
//initialize find
|
//initialize find
|
||||||
@@ -348,8 +353,8 @@ suite('Notebook Find Model', function (): void {
|
|||||||
display_name: 'Python'
|
display_name: 'Python'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
await initNotebookModel(codeContent);
|
await initNotebookModel(codeContent);
|
||||||
//initialize find
|
//initialize find
|
||||||
@@ -380,8 +385,8 @@ suite('Notebook Find Model', function (): void {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
await initNotebookModel(markdownContent);
|
await initNotebookModel(markdownContent);
|
||||||
|
|
||||||
@@ -435,7 +440,7 @@ suite('Notebook Find Model', function (): void {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: 4,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
await initNotebookModel(cellContent);
|
await initNotebookModel(cellContent);
|
||||||
|
|
||||||
@@ -546,7 +551,7 @@ suite('Notebook Find Model', function (): void {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: 4,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
max_find_count = 4;
|
max_find_count = 4;
|
||||||
await initNotebookModel(cellContent);
|
await initNotebookModel(cellContent);
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
|||||||
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
||||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||||
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
|
import { UndoRedoService } from 'vs/platform/undoRedo/common/undoRedoService';
|
||||||
|
import { SQL_NOTEBOOK_PROVIDER } from 'sql/workbench/services/notebook/browser/notebookService';
|
||||||
|
import { NBFORMAT, NBFORMAT_MINOR } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
let expectedNotebookContent: nb.INotebookContents = {
|
let expectedNotebookContent: nb.INotebookContents = {
|
||||||
cells: [{
|
cells: [{
|
||||||
@@ -64,8 +66,8 @@ let expectedNotebookContent: nb.INotebookContents = {
|
|||||||
name: 'sql'
|
name: 'sql'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let expectedNotebookContentOneCell: nb.INotebookContents = {
|
let expectedNotebookContentOneCell: nb.INotebookContents = {
|
||||||
@@ -82,8 +84,8 @@ let expectedNotebookContentOneCell: nb.INotebookContents = {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let expectedKernelAliasNotebookContentOneCell: nb.INotebookContents = {
|
let expectedKernelAliasNotebookContentOneCell: nb.INotebookContents = {
|
||||||
@@ -103,8 +105,8 @@ let expectedKernelAliasNotebookContentOneCell: nb.INotebookContents = {
|
|||||||
version: ''
|
version: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let expectedParameterizedNotebookContent: nb.INotebookContents = {
|
let expectedParameterizedNotebookContent: nb.INotebookContents = {
|
||||||
@@ -126,8 +128,8 @@ let expectedParameterizedNotebookContent: nb.INotebookContents = {
|
|||||||
display_name: 'Python 3'
|
display_name: 'Python 3'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let defaultUri = URI.file('/some/path.ipynb');
|
let defaultUri = URI.file('/some/path.ipynb');
|
||||||
@@ -154,6 +156,7 @@ suite('notebook model', function (): void {
|
|||||||
const logService = new NullLogService();
|
const logService = new NullLogService();
|
||||||
setup(() => {
|
setup(() => {
|
||||||
mockSessionManager = TypeMoq.Mock.ofType(SessionManager);
|
mockSessionManager = TypeMoq.Mock.ofType(SessionManager);
|
||||||
|
executeManagers[0].providerId = SQL_NOTEBOOK_PROVIDER;
|
||||||
executeManagers[0].sessionManager = mockSessionManager.object;
|
executeManagers[0].sessionManager = mockSessionManager.object;
|
||||||
sessionReady = new Deferred<void>();
|
sessionReady = new Deferred<void>();
|
||||||
notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
|
notificationService = TypeMoq.Mock.ofType<INotificationService>(TestNotificationService, TypeMoq.MockBehavior.Loose);
|
||||||
@@ -207,8 +210,8 @@ suite('notebook model', function (): void {
|
|||||||
display_name: 'SQL'
|
display_name: 'SQL'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
|
|
||||||
let mockContentManager = TypeMoq.Mock.ofType(NotebookEditorContentLoader);
|
let mockContentManager = TypeMoq.Mock.ofType(NotebookEditorContentLoader);
|
||||||
@@ -307,9 +310,9 @@ suite('notebook model', function (): void {
|
|||||||
|
|
||||||
// Check that the getters return the correct values
|
// Check that the getters return the correct values
|
||||||
assert.strictEqual(model.executeManagers.length, 2, 'There should be 2 notebook managers');
|
assert.strictEqual(model.executeManagers.length, 2, 'There should be 2 notebook managers');
|
||||||
assert(!isUndefinedOrNull(model.getExecuteManager('SQL')), 'SQL notebook manager is not defined');
|
assert(model.executeManagers.some(m => m.providerId === 'SQL'), 'SQL notebook manager should be defined');
|
||||||
assert(!isUndefinedOrNull(model.getExecuteManager('jupyter')), 'Jupyter notebook manager is not defined');
|
assert(model.executeManagers.some(m => m.providerId === 'jupyter'), 'Jupyter notebook manager should be defined');
|
||||||
assert(isUndefinedOrNull(model.getExecuteManager('foo')), 'foo notebook manager is incorrectly defined');
|
assert(model.executeManagers.every(m => m.providerId !== 'foo'), 'foo notebook manager should not be defined');
|
||||||
|
|
||||||
// Check other properties to ensure that they're returning as expected
|
// Check other properties to ensure that they're returning as expected
|
||||||
// No server manager was passed into the notebook manager stub, so expect hasServerManager to return false
|
// No server manager was passed into the notebook manager stub, so expect hasServerManager to return false
|
||||||
@@ -626,8 +629,8 @@ suite('notebook model', function (): void {
|
|||||||
name: 'sql'
|
name: 'sql'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let mockContentManager = TypeMoq.Mock.ofType(NotebookEditorContentLoader);
|
let mockContentManager = TypeMoq.Mock.ofType(NotebookEditorContentLoader);
|
||||||
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(expectedNotebookContentSplitCells));
|
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(expectedNotebookContentSplitCells));
|
||||||
@@ -905,8 +908,8 @@ suite('notebook model', function (): void {
|
|||||||
metadata: {
|
metadata: {
|
||||||
connection_name: connectionName
|
connection_name: connectionName
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let mockContentManager = TypeMoq.Mock.ofType(NotebookEditorContentLoader);
|
let mockContentManager = TypeMoq.Mock.ofType(NotebookEditorContentLoader);
|
||||||
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(notebook));
|
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(notebook));
|
||||||
@@ -955,8 +958,8 @@ suite('notebook model', function (): void {
|
|||||||
metadata: {
|
metadata: {
|
||||||
multi_connection_mode: true
|
multi_connection_mode: true
|
||||||
},
|
},
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: 5
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
};
|
};
|
||||||
let mockContentManager = TypeMoq.Mock.ofType(NotebookEditorContentLoader);
|
let mockContentManager = TypeMoq.Mock.ofType(NotebookEditorContentLoader);
|
||||||
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(notebook));
|
mockContentManager.setup(c => c.loadContent()).returns(() => Promise.resolve(notebook));
|
||||||
|
|||||||
@@ -41,13 +41,13 @@ suite('notebookUtils', function (): void {
|
|||||||
|
|
||||||
// getStandardKernelsForProvider
|
// getStandardKernelsForProvider
|
||||||
let returnHandler = (provider) => {
|
let returnHandler = (provider) => {
|
||||||
|
let result = undefined;
|
||||||
if (provider === testProvider) {
|
if (provider === testProvider) {
|
||||||
return [testKernel];
|
result = [testKernel];
|
||||||
} else if (provider === SQL_NOTEBOOK_PROVIDER) {
|
} else if (provider === SQL_NOTEBOOK_PROVIDER) {
|
||||||
return [sqlStandardKernel];
|
result = [sqlStandardKernel];
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
|
return Promise.resolve(result);
|
||||||
};
|
};
|
||||||
mockNotebookService.setup(n => n.getStandardKernelsForProvider(TypeMoq.It.isAnyString())).returns(returnHandler);
|
mockNotebookService.setup(n => n.getStandardKernelsForProvider(TypeMoq.It.isAnyString())).returns(returnHandler);
|
||||||
mockNotebookService.setup(n => n.getStandardKernelsForProvider(TypeMoq.It.isAnyString())).returns(returnHandler);
|
mockNotebookService.setup(n => n.getStandardKernelsForProvider(TypeMoq.It.isAnyString())).returns(returnHandler);
|
||||||
@@ -91,19 +91,19 @@ suite('notebookUtils', function (): void {
|
|||||||
test('getStandardKernelsForProvider Test', async function (): Promise<void> {
|
test('getStandardKernelsForProvider Test', async function (): Promise<void> {
|
||||||
setupMockNotebookService();
|
setupMockNotebookService();
|
||||||
|
|
||||||
let result = getStandardKernelsForProvider(undefined, undefined);
|
let result = await getStandardKernelsForProvider(undefined, undefined);
|
||||||
assert.deepStrictEqual(result, []);
|
assert.deepStrictEqual(result, []);
|
||||||
|
|
||||||
result = getStandardKernelsForProvider(undefined, mockNotebookService.object);
|
result = await getStandardKernelsForProvider(undefined, mockNotebookService.object);
|
||||||
assert.deepStrictEqual(result, []);
|
assert.deepStrictEqual(result, []);
|
||||||
|
|
||||||
result = getStandardKernelsForProvider('testProvider', undefined);
|
result = await getStandardKernelsForProvider('testProvider', undefined);
|
||||||
assert.deepStrictEqual(result, []);
|
assert.deepStrictEqual(result, []);
|
||||||
|
|
||||||
result = getStandardKernelsForProvider('NotARealProvider', mockNotebookService.object);
|
result = await getStandardKernelsForProvider('NotARealProvider', mockNotebookService.object);
|
||||||
assert.deepStrictEqual(result, [Object.assign({ notebookProvider: 'NotARealProvider' }, sqlStandardKernel)]);
|
assert.deepStrictEqual(result, [Object.assign({ notebookProvider: 'NotARealProvider' }, sqlStandardKernel)]);
|
||||||
|
|
||||||
result = getStandardKernelsForProvider('testProvider', mockNotebookService.object);
|
result = await getStandardKernelsForProvider('testProvider', mockNotebookService.object);
|
||||||
assert.deepStrictEqual(result, [<IStandardKernelWithProvider>{
|
assert.deepStrictEqual(result, [<IStandardKernelWithProvider>{
|
||||||
name: 'testName',
|
name: 'testName',
|
||||||
displayName: 'testDisplayName',
|
displayName: 'testDisplayName',
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ export class NotebookServiceStub implements INotebookService {
|
|||||||
getProvidersForFileType(fileType: string): string[] {
|
getProvidersForFileType(fileType: string): string[] {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
getStandardKernelsForProvider(provider: string): nb.IStandardKernel[] {
|
getStandardKernelsForProvider(provider: string): Promise<nb.IStandardKernel[]> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
getOrCreateSerializationManager(providerId: string, uri: URI): Promise<ISerializationManager> {
|
getOrCreateSerializationManager(providerId: string, uri: URI): Promise<ISerializationManager> {
|
||||||
|
|||||||
@@ -611,7 +611,8 @@ export class CellModel extends Disposable implements ICellModel {
|
|||||||
if (tryMatchCellMagic(this.source[0]) !== ads_execute_command || !this._isCommandExecutionSettingEnabled) {
|
if (tryMatchCellMagic(this.source[0]) !== ads_execute_command || !this._isCommandExecutionSettingEnabled) {
|
||||||
const future = kernel.requestExecute({
|
const future = kernel.requestExecute({
|
||||||
code: content,
|
code: content,
|
||||||
stop_on_error: true
|
stop_on_error: true,
|
||||||
|
notebookUri: this.notebookModel.notebookUri
|
||||||
}, false);
|
}, false);
|
||||||
this.setFuture(future as FutureInternal);
|
this.setFuture(future as FutureInternal);
|
||||||
this.fireExecutionStateChanged();
|
this.fireExecutionStateChanged();
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ export class ClientSession implements IClientSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async startServer(kernelSpec: nb.IKernelSpec): Promise<void> {
|
private async startServer(kernelSpec: nb.IKernelSpec): Promise<void> {
|
||||||
|
if (!this._executeManager) {
|
||||||
|
throw new Error(localize('NoExecuteManager', "Server could not start because a provider was not defined for this notebook file type."));
|
||||||
|
}
|
||||||
let serverManager = this._executeManager.serverManager;
|
let serverManager = this._executeManager.serverManager;
|
||||||
if (serverManager) {
|
if (serverManager) {
|
||||||
await serverManager.startServer(kernelSpec);
|
await serverManager.startServer(kernelSpec);
|
||||||
|
|||||||
@@ -179,13 +179,6 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getExecuteManager(providerId: string): IExecuteManager | undefined {
|
|
||||||
if (providerId) {
|
|
||||||
return this.executeManagers.find(manager => manager.providerId === providerId);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get notebookOptions(): INotebookModelOptions {
|
public get notebookOptions(): INotebookModelOptions {
|
||||||
return this._notebookOptions;
|
return this._notebookOptions;
|
||||||
}
|
}
|
||||||
@@ -519,7 +512,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
|
|
||||||
public async requestModelLoad(): Promise<void> {
|
public async requestModelLoad(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
this.setDefaultKernelAndProviderId();
|
await this.setDefaultKernelAndProviderId();
|
||||||
this.trySetLanguageFromLangInfo();
|
this.trySetLanguageFromLangInfo();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this._inErrorState = true;
|
this._inErrorState = true;
|
||||||
@@ -975,7 +968,15 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
this._activeClientSession = clientSession;
|
this._activeClientSession = clientSession;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setDefaultKernelAndProviderId() {
|
public async setDefaultKernelAndProviderId(): Promise<void> {
|
||||||
|
if (!this._defaultKernel) {
|
||||||
|
await this.executeManager.sessionManager.ready;
|
||||||
|
if (this.executeManager.sessionManager.specs) {
|
||||||
|
let defaultKernelName = this.executeManager.sessionManager.specs.defaultKernel;
|
||||||
|
this._defaultKernel = this.executeManager.sessionManager.specs.kernels.find(kernel => kernel.name === defaultKernelName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this._capabilitiesService?.providers) {
|
if (this._capabilitiesService?.providers) {
|
||||||
let providers = this._capabilitiesService.providers;
|
let providers = this._capabilitiesService.providers;
|
||||||
for (const server in providers) {
|
for (const server in providers) {
|
||||||
@@ -1416,7 +1417,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
this._onProviderIdChanged.fire(this._providerId);
|
this._onProviderIdChanged.fire(this._providerId);
|
||||||
|
|
||||||
await this.shutdownActiveSession();
|
await this.shutdownActiveSession();
|
||||||
let manager = this.getExecuteManager(providerId);
|
let manager = this.executeManager;
|
||||||
if (manager) {
|
if (manager) {
|
||||||
await this.startSession(manager, displayName, false, kernelAlias);
|
await this.startSession(manager, displayName, false, kernelAlias);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -35,14 +35,14 @@ export function getProvidersForFileName(fileName: string, notebookService: INote
|
|||||||
return providers;
|
return providers;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getStandardKernelsForProvider(providerId: string, notebookService: INotebookService): IStandardKernelWithProvider[] {
|
export async function getStandardKernelsForProvider(providerId: string, notebookService: INotebookService): Promise<IStandardKernelWithProvider[]> {
|
||||||
if (!providerId || !notebookService) {
|
if (!providerId || !notebookService) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
let standardKernels = notebookService.getStandardKernelsForProvider(providerId);
|
let standardKernels = await notebookService.getStandardKernelsForProvider(providerId);
|
||||||
if (!standardKernels || standardKernels.length === 0) {
|
if (!standardKernels || standardKernels.length === 0) {
|
||||||
// Fall back to using SQL provider instead
|
// Fall back to using SQL provider instead
|
||||||
standardKernels = notebookService.getStandardKernelsForProvider(SQL_NOTEBOOK_PROVIDER) ?? [];
|
standardKernels = await notebookService.getStandardKernelsForProvider(SQL_NOTEBOOK_PROVIDER) ?? [];
|
||||||
}
|
}
|
||||||
standardKernels.forEach(kernel => {
|
standardKernels.forEach(kernel => {
|
||||||
Object.assign(<IStandardKernelWithProvider>kernel, {
|
Object.assign(<IStandardKernelWithProvider>kernel, {
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export interface INotebookService {
|
|||||||
|
|
||||||
getProvidersForFileType(fileType: string): string[] | undefined;
|
getProvidersForFileType(fileType: string): string[] | undefined;
|
||||||
|
|
||||||
getStandardKernelsForProvider(provider: string): azdata.nb.IStandardKernel[] | undefined;
|
getStandardKernelsForProvider(provider: string): Promise<azdata.nb.IStandardKernel[] | undefined>;
|
||||||
|
|
||||||
getOrCreateSerializationManager(providerId: string, uri: URI): Promise<ISerializationManager>;
|
getOrCreateSerializationManager(providerId: string, uri: URI): Promise<ISerializationManager>;
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editor
|
|||||||
import { IEditorInput, IEditorPane } from 'vs/workbench/common/editor';
|
import { IEditorInput, IEditorPane } from 'vs/workbench/common/editor';
|
||||||
import { isINotebookInput } from 'sql/workbench/services/notebook/browser/interface';
|
import { isINotebookInput } from 'sql/workbench/services/notebook/browser/interface';
|
||||||
import { INotebookShowOptions } from 'sql/workbench/api/common/sqlExtHost.protocol';
|
import { INotebookShowOptions } from 'sql/workbench/api/common/sqlExtHost.protocol';
|
||||||
import { NotebookLanguage } from 'sql/workbench/common/constants';
|
import { JUPYTER_PROVIDER_ID, NotebookLanguage } from 'sql/workbench/common/constants';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { SqlSerializationProvider } from 'sql/workbench/services/notebook/browser/sql/sqlSerializationProvider';
|
import { SqlSerializationProvider } from 'sql/workbench/services/notebook/browser/sql/sqlSerializationProvider';
|
||||||
|
|
||||||
@@ -134,6 +134,31 @@ export class ExecuteProviderDescriptor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class StandardKernelsDescriptor {
|
||||||
|
private _instanceReady = new Deferred<nb.IStandardKernel[]>();
|
||||||
|
constructor(private readonly _providerId: string, private _instance?: nb.IStandardKernel[]) {
|
||||||
|
if (_instance) {
|
||||||
|
this._instanceReady.resolve(_instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get providerId(): string {
|
||||||
|
return this._providerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get instanceReady(): Promise<nb.IStandardKernel[]> {
|
||||||
|
return this._instanceReady.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get instance(): nb.IStandardKernel[] | undefined {
|
||||||
|
return this._instance;
|
||||||
|
}
|
||||||
|
public set instance(value: nb.IStandardKernel[]) {
|
||||||
|
this._instance = value;
|
||||||
|
this._instanceReady.resolve(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const NotebookUriNotDefined = localize('notebookUriNotDefined', "No URI was passed when creating a notebook manager");
|
export const NotebookUriNotDefined = localize('notebookUriNotDefined', "No URI was passed when creating a notebook manager");
|
||||||
export const NotebookServiceNoProviderRegistered = localize('notebookServiceNoProvider', "Notebook provider does not exist");
|
export const NotebookServiceNoProviderRegistered = localize('notebookServiceNoProvider', "Notebook provider does not exist");
|
||||||
export const FailToSaveTrustState = 'Failed to save trust state to cache';
|
export const FailToSaveTrustState = 'Failed to save trust state to cache';
|
||||||
@@ -154,7 +179,7 @@ export class NotebookService extends Disposable implements INotebookService {
|
|||||||
private _onNotebookEditorRename = new Emitter<INotebookEditor>();
|
private _onNotebookEditorRename = new Emitter<INotebookEditor>();
|
||||||
private _editors = new Map<string, INotebookEditor>();
|
private _editors = new Map<string, INotebookEditor>();
|
||||||
private _fileToProviderDescriptions = new Map<string, ProviderDescriptionRegistration[]>();
|
private _fileToProviderDescriptions = new Map<string, ProviderDescriptionRegistration[]>();
|
||||||
private _providerToStandardKernels = new Map<string, nb.IStandardKernel[]>();
|
private _providerToStandardKernels = new Map<string, StandardKernelsDescriptor>();
|
||||||
private _registrationComplete = new Deferred<void>();
|
private _registrationComplete = new Deferred<void>();
|
||||||
private _isRegistrationComplete = false;
|
private _isRegistrationComplete = false;
|
||||||
private _trustedCacheQueue: URI[] = [];
|
private _trustedCacheQueue: URI[] = [];
|
||||||
@@ -291,13 +316,14 @@ export class NotebookService extends Disposable implements INotebookService {
|
|||||||
let sqlNotebookKernels = this._providerToStandardKernels.get(notebookConstants.SQL);
|
let sqlNotebookKernels = this._providerToStandardKernels.get(notebookConstants.SQL);
|
||||||
if (sqlNotebookKernels) {
|
if (sqlNotebookKernels) {
|
||||||
let sqlConnectionTypes = this._queryManagementService.getRegisteredProviders();
|
let sqlConnectionTypes = this._queryManagementService.getRegisteredProviders();
|
||||||
let kernel = sqlNotebookKernels.find(p => p.name === notebookConstants.SQL);
|
let kernel = sqlNotebookKernels.instance.find(p => p.name === notebookConstants.SQL);
|
||||||
if (kernel) {
|
if (kernel) {
|
||||||
this._providerToStandardKernels.set(notebookConstants.SQL, [{
|
let descriptor = new StandardKernelsDescriptor(notebookConstants.SQL, [{
|
||||||
name: notebookConstants.SQL,
|
name: notebookConstants.SQL,
|
||||||
displayName: notebookConstants.SQL,
|
displayName: notebookConstants.SQL,
|
||||||
connectionProviderIds: sqlConnectionTypes
|
connectionProviderIds: sqlConnectionTypes
|
||||||
}]);
|
}]);
|
||||||
|
this._providerToStandardKernels.set(notebookConstants.SQL, descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._isRegistrationComplete = true;
|
this._isRegistrationComplete = true;
|
||||||
@@ -325,6 +351,17 @@ export class NotebookService extends Disposable implements INotebookService {
|
|||||||
this._executeProviders.set(p.id, new ExecuteProviderDescriptor(p.id));
|
this._executeProviders.set(p.id, new ExecuteProviderDescriptor(p.id));
|
||||||
}
|
}
|
||||||
this.addStandardKernels(registration);
|
this.addStandardKernels(registration);
|
||||||
|
} else {
|
||||||
|
// Standard kernels might get registered later for VSCode notebooks, so add a descriptor to wait on
|
||||||
|
let descriptor = new StandardKernelsDescriptor(p.id);
|
||||||
|
this._providerToStandardKernels.set(p.id.toUpperCase(), descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emit activation event if the provider is not one of the default options
|
||||||
|
if (p.id !== SQL_NOTEBOOK_PROVIDER && p.id !== JUPYTER_PROVIDER_ID) {
|
||||||
|
this._extensionService.whenInstalledExtensionsRegistered().then(() => {
|
||||||
|
this._extensionService.activateByEvent(`onNotebook:${p.id}`).catch(err => onUnexpectedError(err));
|
||||||
|
}).catch(err => onUnexpectedError(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,18 +429,24 @@ export class NotebookService extends Disposable implements INotebookService {
|
|||||||
// kernels to the dropdown
|
// kernels to the dropdown
|
||||||
private addStandardKernels(provider: ProviderDescriptionRegistration) {
|
private addStandardKernels(provider: ProviderDescriptionRegistration) {
|
||||||
let providerUpperCase = provider.provider.toUpperCase();
|
let providerUpperCase = provider.provider.toUpperCase();
|
||||||
let standardKernels = this._providerToStandardKernels.get(providerUpperCase);
|
let descriptor = this._providerToStandardKernels.get(providerUpperCase);
|
||||||
|
if (!descriptor) {
|
||||||
|
descriptor = new StandardKernelsDescriptor(provider.provider);
|
||||||
|
}
|
||||||
|
let standardKernels = descriptor.instance;
|
||||||
if (!standardKernels) {
|
if (!standardKernels) {
|
||||||
standardKernels = [];
|
standardKernels = [];
|
||||||
}
|
}
|
||||||
provider.standardKernels.forEach(kernel => {
|
provider.standardKernels.forEach(kernel => {
|
||||||
standardKernels.push(kernel);
|
standardKernels.push(kernel);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Filter out unusable kernels when running on a SAW
|
// Filter out unusable kernels when running on a SAW
|
||||||
if (this.productService.quality === 'saw') {
|
if (this.productService.quality === 'saw') {
|
||||||
standardKernels = standardKernels.filter(kernel => !kernel.blockedOnSAW);
|
standardKernels = standardKernels.filter(kernel => !kernel.blockedOnSAW);
|
||||||
}
|
}
|
||||||
this._providerToStandardKernels.set(providerUpperCase, standardKernels);
|
descriptor.instance = standardKernels;
|
||||||
|
this._providerToStandardKernels.set(providerUpperCase, descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
getSupportedFileExtensions(): string[] {
|
getSupportedFileExtensions(): string[] {
|
||||||
@@ -415,8 +458,12 @@ export class NotebookService extends Disposable implements INotebookService {
|
|||||||
return providers?.map(provider => provider.provider);
|
return providers?.map(provider => provider.provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStandardKernelsForProvider(provider: string): nb.IStandardKernel[] | undefined {
|
public async getStandardKernelsForProvider(provider: string): Promise<nb.IStandardKernel[] | undefined> {
|
||||||
return this._providerToStandardKernels.get(provider.toUpperCase());
|
let descriptor = this._providerToStandardKernels.get(provider.toUpperCase());
|
||||||
|
if (descriptor) {
|
||||||
|
return this.waitOnStandardKernelsAvailability(descriptor);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
private shutdown(): void {
|
private shutdown(): void {
|
||||||
@@ -588,11 +635,12 @@ export class NotebookService extends Disposable implements INotebookService {
|
|||||||
|
|
||||||
private async getExecuteProviderInstance(providerId: string, timeout?: number): Promise<IExecuteProvider> {
|
private async getExecuteProviderInstance(providerId: string, timeout?: number): Promise<IExecuteProvider> {
|
||||||
let providerDescriptor = this._executeProviders.get(providerId);
|
let providerDescriptor = this._executeProviders.get(providerId);
|
||||||
|
let kernelDescriptor = this._providerToStandardKernels.get(providerId.toUpperCase());
|
||||||
let instance: IExecuteProvider;
|
let instance: IExecuteProvider;
|
||||||
|
|
||||||
// Try get from actual provider, waiting on its registration
|
// Try get from actual provider, waiting on its registration
|
||||||
if (providerDescriptor) {
|
if (providerDescriptor && kernelDescriptor) {
|
||||||
if (!providerDescriptor.instance) {
|
if (!providerDescriptor.instance || !kernelDescriptor.instance) {
|
||||||
// Await extension registration before awaiting provider registration
|
// Await extension registration before awaiting provider registration
|
||||||
try {
|
try {
|
||||||
await this._extensionService.whenInstalledExtensionsRegistered();
|
await this._extensionService.whenInstalledExtensionsRegistered();
|
||||||
@@ -600,6 +648,12 @@ export class NotebookService extends Disposable implements INotebookService {
|
|||||||
this._logService.error(error);
|
this._logService.error(error);
|
||||||
}
|
}
|
||||||
instance = await this.waitOnExecuteProviderAvailability(providerDescriptor, timeout);
|
instance = await this.waitOnExecuteProviderAvailability(providerDescriptor, timeout);
|
||||||
|
if (instance) {
|
||||||
|
let kernels = await this.waitOnStandardKernelsAvailability(kernelDescriptor, timeout);
|
||||||
|
if (!kernels) {
|
||||||
|
instance = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
instance = providerDescriptor.instance;
|
instance = providerDescriptor.instance;
|
||||||
}
|
}
|
||||||
@@ -621,9 +675,12 @@ export class NotebookService extends Disposable implements INotebookService {
|
|||||||
private waitOnSerializationProviderAvailability(providerDescriptor: SerializationProviderDescriptor, timeout?: number): Promise<ISerializationProvider | undefined> {
|
private waitOnSerializationProviderAvailability(providerDescriptor: SerializationProviderDescriptor, timeout?: number): Promise<ISerializationProvider | undefined> {
|
||||||
// Wait up to 30 seconds for the provider to be registered
|
// Wait up to 30 seconds for the provider to be registered
|
||||||
timeout = timeout ?? 30000;
|
timeout = timeout ?? 30000;
|
||||||
let promises: Promise<ISerializationProvider>[] = [
|
let promises: Promise<ISerializationProvider | undefined>[] = [
|
||||||
providerDescriptor.instanceReady,
|
providerDescriptor.instanceReady,
|
||||||
new Promise<ISerializationProvider>((resolve, reject) => setTimeout(() => resolve(undefined), timeout))
|
new Promise<ISerializationProvider | undefined>((resolve, reject) => setTimeout(() => {
|
||||||
|
onUnexpectedError(localize('serializationProviderTimeout', 'Waiting for Serialization Provider availability timed out for notebook provider \'{0}\'', providerDescriptor.providerId));
|
||||||
|
resolve(undefined);
|
||||||
|
}, timeout))
|
||||||
];
|
];
|
||||||
return Promise.race(promises);
|
return Promise.race(promises);
|
||||||
}
|
}
|
||||||
@@ -631,9 +688,25 @@ export class NotebookService extends Disposable implements INotebookService {
|
|||||||
private waitOnExecuteProviderAvailability(providerDescriptor: ExecuteProviderDescriptor, timeout?: number): Promise<IExecuteProvider | undefined> {
|
private waitOnExecuteProviderAvailability(providerDescriptor: ExecuteProviderDescriptor, timeout?: number): Promise<IExecuteProvider | undefined> {
|
||||||
// Wait up to 30 seconds for the provider to be registered
|
// Wait up to 30 seconds for the provider to be registered
|
||||||
timeout = timeout ?? 30000;
|
timeout = timeout ?? 30000;
|
||||||
let promises: Promise<IExecuteProvider>[] = [
|
let promises: Promise<IExecuteProvider | undefined>[] = [
|
||||||
providerDescriptor.instanceReady,
|
providerDescriptor.instanceReady,
|
||||||
new Promise<IExecuteProvider>((resolve, reject) => setTimeout(() => resolve(undefined), timeout))
|
new Promise<IExecuteProvider | undefined>((resolve, reject) => setTimeout(() => {
|
||||||
|
onUnexpectedError(localize('executeProviderTimeout', 'Waiting for Execute Provider availability timed out for notebook provider \'{0}\'', providerDescriptor.providerId));
|
||||||
|
resolve(undefined);
|
||||||
|
}, timeout))
|
||||||
|
];
|
||||||
|
return Promise.race(promises);
|
||||||
|
}
|
||||||
|
|
||||||
|
private waitOnStandardKernelsAvailability(kernelsDescriptor: StandardKernelsDescriptor, timeout?: number): Promise<nb.IStandardKernel[] | undefined> {
|
||||||
|
// Wait up to 30 seconds for the kernels to be registered
|
||||||
|
timeout = timeout ?? 30000;
|
||||||
|
let promises: Promise<nb.IStandardKernel[] | undefined>[] = [
|
||||||
|
kernelsDescriptor.instanceReady,
|
||||||
|
new Promise<nb.IStandardKernel[] | undefined>((resolve, reject) => setTimeout(() => {
|
||||||
|
onUnexpectedError(localize('standardKernelsTimeout', 'Waiting for Standard Kernels availability timed out for notebook provider \'{0}\'', kernelsDescriptor.providerId));
|
||||||
|
resolve(undefined);
|
||||||
|
}, timeout))
|
||||||
];
|
];
|
||||||
return Promise.race(promises);
|
return Promise.race(promises);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { JSONObject } from 'sql/workbench/services/notebook/common/jsonext';
|
|||||||
import { OutputTypes } from 'sql/workbench/services/notebook/common/contracts';
|
import { OutputTypes } from 'sql/workbench/services/notebook/common/contracts';
|
||||||
import { nbversion } from 'sql/workbench/services/notebook/common/notebookConstants';
|
import { nbversion } from 'sql/workbench/services/notebook/common/notebookConstants';
|
||||||
import { nbformat } from 'sql/workbench/services/notebook/common/nbformat';
|
import { nbformat } from 'sql/workbench/services/notebook/common/nbformat';
|
||||||
|
import { NBFORMAT } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
type MimeBundle = { [key: string]: string | string[] | undefined };
|
type MimeBundle = { [key: string]: string | string[] | undefined };
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ namespace v4 {
|
|||||||
let notebook: nb.INotebookContents = {
|
let notebook: nb.INotebookContents = {
|
||||||
cells: [],
|
cells: [],
|
||||||
metadata: contents.metadata,
|
metadata: contents.metadata,
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: contents.nbformat_minor
|
nbformat_minor: contents.nbformat_minor
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -206,7 +207,7 @@ namespace v3 {
|
|||||||
cells: [],
|
cells: [],
|
||||||
metadata: contents.metadata,
|
metadata: contents.metadata,
|
||||||
// Note: upgrading to v4 as we're converting to our codebase
|
// Note: upgrading to v4 as we're converting to our codebase
|
||||||
nbformat: 4,
|
nbformat: NBFORMAT,
|
||||||
nbformat_minor: nbversion.MINOR_VERSION
|
nbformat_minor: nbversion.MINOR_VERSION
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ export interface INotebookProviderRegistry {
|
|||||||
|
|
||||||
readonly onNewDescriptionRegistration: Event<{ id: string, registration: ProviderDescriptionRegistration }>;
|
readonly onNewDescriptionRegistration: Event<{ id: string, registration: ProviderDescriptionRegistration }>;
|
||||||
|
|
||||||
|
updateProviderDescriptionLanguages(providerId: string, languages: string[]): void;
|
||||||
registerProviderDescription(provider: ProviderDescriptionRegistration): void;
|
registerProviderDescription(provider: ProviderDescriptionRegistration): void;
|
||||||
registerNotebookLanguageMagic(magic: NotebookLanguageMagicRegistration): void;
|
registerNotebookLanguageMagic(magic: NotebookLanguageMagicRegistration): void;
|
||||||
}
|
}
|
||||||
@@ -123,6 +124,24 @@ class NotebookProviderRegistry implements INotebookProviderRegistry {
|
|||||||
private _onNewDescriptionRegistration = new Emitter<{ id: string, registration: ProviderDescriptionRegistration }>();
|
private _onNewDescriptionRegistration = new Emitter<{ id: string, registration: ProviderDescriptionRegistration }>();
|
||||||
public readonly onNewDescriptionRegistration: Event<{ id: string, registration: ProviderDescriptionRegistration }> = this._onNewDescriptionRegistration.event;
|
public readonly onNewDescriptionRegistration: Event<{ id: string, registration: ProviderDescriptionRegistration }> = this._onNewDescriptionRegistration.event;
|
||||||
|
|
||||||
|
updateProviderDescriptionLanguages(providerId: string, languages: string[]): void {
|
||||||
|
let registration = this._providerDescriptionRegistration.get(providerId);
|
||||||
|
if (!registration) {
|
||||||
|
throw new Error(localize('providerNotInRegistryError', "The specified provider '{0}' is not present in the notebook registry.", providerId));
|
||||||
|
}
|
||||||
|
let kernels = languages.map<azdata.nb.IStandardKernel>(language => {
|
||||||
|
return {
|
||||||
|
name: language,
|
||||||
|
displayName: language,
|
||||||
|
connectionProviderIds: []
|
||||||
|
};
|
||||||
|
});
|
||||||
|
registration.standardKernels = kernels;
|
||||||
|
|
||||||
|
// Update provider description with new info
|
||||||
|
this.registerProviderDescription(registration);
|
||||||
|
}
|
||||||
|
|
||||||
registerProviderDescription(registration: ProviderDescriptionRegistration): void {
|
registerProviderDescription(registration: ProviderDescriptionRegistration): void {
|
||||||
this._providerDescriptionRegistration.set(registration.provider, registration);
|
this._providerDescriptionRegistration.set(registration.provider, registration);
|
||||||
this._onNewDescriptionRegistration.fire({ id: registration.provider, registration: registration });
|
this._onNewDescriptionRegistration.fire({ id: registration.provider, registration: registration });
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKe
|
|||||||
import { ExtHostNotebookShape } from 'sql/workbench/api/common/sqlExtHost.protocol';
|
import { ExtHostNotebookShape } from 'sql/workbench/api/common/sqlExtHost.protocol';
|
||||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||||
import { IProductService } from 'vs/platform/product/common/productService';
|
import { IProductService } from 'vs/platform/product/common/productService';
|
||||||
|
import { Disposable, NotebookCell, NotebookController, NotebookDocument, NotebookDocumentContentOptions, NotebookRegistrationData, NotebookRendererScript, NotebookSerializer } from 'vscode';
|
||||||
|
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||||
|
|
||||||
suite('MainThreadNotebook Tests', () => {
|
suite('MainThreadNotebook Tests', () => {
|
||||||
|
|
||||||
@@ -181,6 +183,18 @@ suite('MainThreadNotebook Tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
class ExtHostNotebookStub implements ExtHostNotebookShape {
|
class ExtHostNotebookStub implements ExtHostNotebookShape {
|
||||||
|
$registerExecuteProvider(provider: azdata.nb.NotebookExecuteProvider): Disposable {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
$registerSerializationProvider(provider: azdata.nb.NotebookSerializationProvider): Disposable {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
$registerNotebookSerializer(notebookType: string, serializer: NotebookSerializer, options?: NotebookDocumentContentOptions, registration?: NotebookRegistrationData): Disposable {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
|
$createNotebookController(extension: IExtensionDescription, id: string, viewType: string, label: string, handler?: (cells: NotebookCell[], notebook: NotebookDocument, controller: NotebookController) => void | Thenable<void>, rendererScripts?: NotebookRendererScript[]): NotebookController {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
$getSerializationManagerDetails(providerHandle: number, notebookUri: UriComponents): Thenable<ISerializationManagerDetails> {
|
$getSerializationManagerDetails(providerHandle: number, notebookUri: UriComponents): Thenable<ISerializationManagerDetails> {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,338 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import { VSCodeContentManager } from 'sql/workbench/api/common/vscodeSerializationProvider';
|
||||||
|
import type * as vscode from 'vscode';
|
||||||
|
import type * as azdata from 'azdata';
|
||||||
|
import * as sinon from 'sinon';
|
||||||
|
import { NotebookCellKind } from 'vs/workbench/api/common/extHostTypes';
|
||||||
|
import { VSBuffer } from 'vs/base/common/buffer';
|
||||||
|
import * as assert from 'assert';
|
||||||
|
import { OutputTypes } from 'sql/workbench/services/notebook/common/contracts';
|
||||||
|
import { NBFORMAT, NBFORMAT_MINOR } from 'sql/workbench/common/constants';
|
||||||
|
|
||||||
|
class MockNotebookSerializer implements vscode.NotebookSerializer {
|
||||||
|
deserializeNotebook(content: Uint8Array, token: vscode.CancellationToken): vscode.NotebookData | Thenable<vscode.NotebookData> {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
serializeNotebook(data: vscode.NotebookData, token: vscode.CancellationToken): Uint8Array | Thenable<Uint8Array> {
|
||||||
|
return new Uint8Array([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suite('Notebook Serializer', () => {
|
||||||
|
let contentManager: VSCodeContentManager;
|
||||||
|
let sandbox: sinon.SinonSandbox;
|
||||||
|
let serializeSpy: sinon.SinonSpy;
|
||||||
|
|
||||||
|
const deserializeResult: vscode.NotebookData = {
|
||||||
|
cells: [{
|
||||||
|
kind: NotebookCellKind.Code,
|
||||||
|
value: '1+1',
|
||||||
|
languageId: 'python',
|
||||||
|
outputs: [{
|
||||||
|
id: '1',
|
||||||
|
items: [{
|
||||||
|
mime: 'text/plain',
|
||||||
|
data: VSBuffer.fromString('2').buffer
|
||||||
|
}],
|
||||||
|
metadata: {}
|
||||||
|
}],
|
||||||
|
executionSummary: {
|
||||||
|
executionOrder: 1
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
kind: NotebookCellKind.Code,
|
||||||
|
value: 'print(1)',
|
||||||
|
languageId: 'python',
|
||||||
|
outputs: [{
|
||||||
|
id: '2',
|
||||||
|
items: [{
|
||||||
|
mime: 'text/plain',
|
||||||
|
data: VSBuffer.fromString('1').buffer
|
||||||
|
}],
|
||||||
|
metadata: {}
|
||||||
|
}],
|
||||||
|
executionSummary: {
|
||||||
|
executionOrder: 2
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
metadata: {
|
||||||
|
kernelspec: {
|
||||||
|
name: 'python3',
|
||||||
|
display_name: 'Python 3',
|
||||||
|
language: 'python'
|
||||||
|
},
|
||||||
|
language_info: {
|
||||||
|
name: 'python',
|
||||||
|
version: '3.8.10',
|
||||||
|
mimetype: 'text/x-python',
|
||||||
|
codemirror_mode: {
|
||||||
|
name: 'ipython',
|
||||||
|
version: '3'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
custom: {
|
||||||
|
nbformat: NBFORMAT,
|
||||||
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedDeserializedNotebook: azdata.nb.INotebookContents = {
|
||||||
|
metadata: {
|
||||||
|
kernelspec: {
|
||||||
|
name: 'python3',
|
||||||
|
display_name: 'Python 3',
|
||||||
|
language: 'python'
|
||||||
|
},
|
||||||
|
language_info: {
|
||||||
|
name: 'python',
|
||||||
|
version: '3.8.10',
|
||||||
|
mimetype: 'text/x-python',
|
||||||
|
codemirror_mode: {
|
||||||
|
name: 'ipython',
|
||||||
|
version: '3'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
nbformat: NBFORMAT,
|
||||||
|
nbformat_minor: NBFORMAT_MINOR,
|
||||||
|
cells: [
|
||||||
|
{
|
||||||
|
cell_type: 'code',
|
||||||
|
source: '1+1',
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
output_type: 'execute_result',
|
||||||
|
data: {
|
||||||
|
'text/plain': '2'
|
||||||
|
},
|
||||||
|
metadata: {},
|
||||||
|
execution_count: 1
|
||||||
|
} as azdata.nb.IExecuteResult
|
||||||
|
],
|
||||||
|
execution_count: 1,
|
||||||
|
metadata: {
|
||||||
|
language: 'python'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
cell_type: 'code',
|
||||||
|
source: 'print(1)',
|
||||||
|
outputs: [
|
||||||
|
{
|
||||||
|
id: '2',
|
||||||
|
output_type: 'execute_result',
|
||||||
|
data: {
|
||||||
|
'text/plain': '1'
|
||||||
|
},
|
||||||
|
metadata: {},
|
||||||
|
execution_count: 2
|
||||||
|
} as azdata.nb.IExecuteResult
|
||||||
|
],
|
||||||
|
execution_count: 2,
|
||||||
|
metadata: {
|
||||||
|
language: 'python'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const expectedSerializeArg: vscode.NotebookData = {
|
||||||
|
cells: [{
|
||||||
|
kind: NotebookCellKind.Code,
|
||||||
|
value: '1+1',
|
||||||
|
languageId: 'python',
|
||||||
|
outputs: [{
|
||||||
|
items: [{
|
||||||
|
mime: 'text/plain',
|
||||||
|
data: VSBuffer.fromString('2').buffer
|
||||||
|
}],
|
||||||
|
metadata: {},
|
||||||
|
id: '1'
|
||||||
|
}],
|
||||||
|
executionSummary: {
|
||||||
|
executionOrder: 1
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
kind: NotebookCellKind.Code,
|
||||||
|
value: 'print(1)',
|
||||||
|
languageId: 'python',
|
||||||
|
outputs: [{
|
||||||
|
items: [{
|
||||||
|
mime: 'text/plain',
|
||||||
|
data: VSBuffer.fromString('1').buffer
|
||||||
|
}],
|
||||||
|
metadata: {},
|
||||||
|
id: '2'
|
||||||
|
}],
|
||||||
|
executionSummary: {
|
||||||
|
executionOrder: 2
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
metadata: {
|
||||||
|
kernelspec: {
|
||||||
|
name: 'python3',
|
||||||
|
display_name: 'Python 3',
|
||||||
|
language: 'python'
|
||||||
|
},
|
||||||
|
language_info: {
|
||||||
|
name: 'python',
|
||||||
|
version: '3.8.10',
|
||||||
|
mimetype: 'text/x-python',
|
||||||
|
codemirror_mode: {
|
||||||
|
name: 'ipython',
|
||||||
|
version: '3'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
custom: {
|
||||||
|
nbformat: NBFORMAT,
|
||||||
|
nbformat_minor: NBFORMAT_MINOR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
setup(() => {
|
||||||
|
sandbox = sinon.createSandbox();
|
||||||
|
let serializer = new MockNotebookSerializer();
|
||||||
|
sandbox.stub(serializer, 'deserializeNotebook').returns(deserializeResult);
|
||||||
|
serializeSpy = sandbox.spy(serializer, 'serializeNotebook');
|
||||||
|
|
||||||
|
contentManager = new VSCodeContentManager(serializer);
|
||||||
|
});
|
||||||
|
|
||||||
|
teardown(() => {
|
||||||
|
sandbox.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test('Convert VSCode notebook output to ADS notebook output', async () => {
|
||||||
|
let cellOutput: vscode.NotebookCellOutput = {
|
||||||
|
items: [{
|
||||||
|
mime: 'text/plain',
|
||||||
|
data: VSBuffer.fromString('2').buffer
|
||||||
|
}, {
|
||||||
|
mime: 'text/html',
|
||||||
|
data: VSBuffer.fromString('<i>2</i>').buffer
|
||||||
|
}],
|
||||||
|
metadata: {},
|
||||||
|
id: '1'
|
||||||
|
};
|
||||||
|
let expectedADSOutput: azdata.nb.IExecuteResult = {
|
||||||
|
id: '1',
|
||||||
|
output_type: 'execute_result',
|
||||||
|
data: {
|
||||||
|
'text/plain': '2',
|
||||||
|
'text/html': '<i>2</i>'
|
||||||
|
},
|
||||||
|
metadata: {},
|
||||||
|
execution_count: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
let actualOutput = VSCodeContentManager.convertToADSCellOutput(cellOutput, 1);
|
||||||
|
assert.deepStrictEqual(actualOutput, expectedADSOutput);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Convert ADS notebook execute result to VSCode notebook output', async () => {
|
||||||
|
let cellOutput: azdata.nb.IExecuteResult = {
|
||||||
|
id: 'testId',
|
||||||
|
output_type: OutputTypes.ExecuteResult,
|
||||||
|
data: {
|
||||||
|
'text/plain': 'abc',
|
||||||
|
'text/html': '<i>abc</i>'
|
||||||
|
},
|
||||||
|
execution_count: 1
|
||||||
|
};
|
||||||
|
let expectedVSCodeOutput: vscode.NotebookCellOutput = {
|
||||||
|
items: [{
|
||||||
|
mime: 'text/plain',
|
||||||
|
data: VSBuffer.fromString('abc').buffer
|
||||||
|
}, {
|
||||||
|
mime: 'text/html',
|
||||||
|
data: VSBuffer.fromString('<i>abc</i>').buffer
|
||||||
|
}],
|
||||||
|
id: 'testId',
|
||||||
|
metadata: undefined
|
||||||
|
};
|
||||||
|
let actualOutput = VSCodeContentManager.convertToVSCodeCellOutput(cellOutput);
|
||||||
|
assert.deepStrictEqual(actualOutput, expectedVSCodeOutput);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Convert ADS notebook stream result to VSCode notebook output', async () => {
|
||||||
|
let cellOutput: azdata.nb.IStreamResult = {
|
||||||
|
id: 'testId',
|
||||||
|
output_type: 'stream',
|
||||||
|
name: 'stdout',
|
||||||
|
text: [
|
||||||
|
'abc'
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let expectedVSCodeOutput: vscode.NotebookCellOutput = {
|
||||||
|
items: [{
|
||||||
|
mime: 'text/html',
|
||||||
|
data: VSBuffer.fromString('abc').buffer
|
||||||
|
}],
|
||||||
|
id: 'testId',
|
||||||
|
metadata: undefined
|
||||||
|
};
|
||||||
|
let actualOutput = VSCodeContentManager.convertToVSCodeCellOutput(cellOutput);
|
||||||
|
assert.deepStrictEqual(actualOutput, expectedVSCodeOutput);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Convert ADS notebook error with trace to VSCode notebook output', async () => {
|
||||||
|
let cellOutput: azdata.nb.IErrorResult = {
|
||||||
|
id: 'testId',
|
||||||
|
output_type: 'error',
|
||||||
|
ename: 'TestException',
|
||||||
|
evalue: 'Expected test error',
|
||||||
|
traceback: ['Trace line 1', 'Trace line 2']
|
||||||
|
};
|
||||||
|
let expectedVSCodeOutput: vscode.NotebookCellOutput = {
|
||||||
|
items: [{
|
||||||
|
mime: 'text/html',
|
||||||
|
data: VSBuffer.fromString('TestException: Expected test error\nTrace line 1\nTrace line 2').buffer
|
||||||
|
}],
|
||||||
|
id: 'testId',
|
||||||
|
metadata: undefined
|
||||||
|
};
|
||||||
|
let actualOutput = VSCodeContentManager.convertToVSCodeCellOutput(cellOutput);
|
||||||
|
assert.deepStrictEqual(actualOutput, expectedVSCodeOutput);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Convert ADS notebook error without trace to VSCode notebook output', async () => {
|
||||||
|
let cellOutput: azdata.nb.IErrorResult = {
|
||||||
|
id: 'testId',
|
||||||
|
output_type: 'error',
|
||||||
|
ename: 'TestException',
|
||||||
|
evalue: 'Expected test error'
|
||||||
|
};
|
||||||
|
let expectedVSCodeOutput: vscode.NotebookCellOutput = {
|
||||||
|
items: [{
|
||||||
|
mime: 'text/html',
|
||||||
|
data: VSBuffer.fromString('TestException: Expected test error').buffer
|
||||||
|
}],
|
||||||
|
id: 'testId',
|
||||||
|
metadata: undefined
|
||||||
|
};
|
||||||
|
let actualOutput = VSCodeContentManager.convertToVSCodeCellOutput(cellOutput);
|
||||||
|
assert.deepStrictEqual(actualOutput, expectedVSCodeOutput);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Deserialize VSCode notebook into ADS notebook data', async () => {
|
||||||
|
let output = await contentManager.deserializeNotebook(''); // Argument is ignored since we're returning a mocked result
|
||||||
|
assert.deepStrictEqual(output, expectedDeserializedNotebook);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Serialize ADS notebook data into VSCode notebook strings', async () => {
|
||||||
|
await contentManager.serializeNotebook(expectedDeserializedNotebook); // Argument is ignored since we're returning a mocked result
|
||||||
|
assert(serializeSpy.calledOnce);
|
||||||
|
assert.deepStrictEqual(serializeSpy.firstCall.args[0], expectedSerializeArg);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
suite('Notebook Controller', () => {
|
||||||
|
});
|
||||||
@@ -8,13 +8,13 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
|||||||
import { Emitter } from 'vs/base/common/event';
|
import { Emitter } from 'vs/base/common/event';
|
||||||
import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
import { DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||||
import { URI } from 'vs/base/common/uri';
|
import { URI } from 'vs/base/common/uri';
|
||||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
// import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService';
|
import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/common/notebookCellStatusBarService';
|
||||||
import { INotebookCellStatusBarItemProvider, INotebookContributionData, NotebookDataDto, TransientCellMetadata, TransientDocumentMetadata, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
import { INotebookCellStatusBarItemProvider, INotebookContributionData, NotebookDataDto, TransientCellMetadata, TransientDocumentMetadata, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||||
import { INotebookContentProvider, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
import { INotebookContentProvider, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||||
import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, MainContext, MainThreadNotebookShape, NotebookExtensionDescription } from '../common/extHost.protocol';
|
import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, MainThreadNotebookShape, NotebookExtensionDescription } from '../common/extHost.protocol'; // {{SQL CARBON EDIT}} Remove MainContext
|
||||||
|
|
||||||
@extHostNamedCustomer(MainContext.MainThreadNotebook)
|
// @extHostNamedCustomer(MainContext.MainThreadNotebook) {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
export class MainThreadNotebooks implements MainThreadNotebookShape {
|
export class MainThreadNotebooks implements MainThreadNotebookShape {
|
||||||
|
|
||||||
private readonly _disposables = new DisposableStore();
|
private readonly _disposables = new DisposableStore();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri';
|
|||||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { MainThreadNotebookDocuments } from 'vs/workbench/api/browser/mainThreadNotebookDocuments';
|
import { MainThreadNotebookDocuments } from 'vs/workbench/api/browser/mainThreadNotebookDocuments';
|
||||||
import { MainThreadNotebookEditors } from 'vs/workbench/api/browser/mainThreadNotebookEditors';
|
import { MainThreadNotebookEditors } from 'vs/workbench/api/browser/mainThreadNotebookEditors';
|
||||||
import { extHostCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
// import { extHostCustomer } from 'vs/workbench/api/common/extHostCustomers'; {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
import { editorGroupToViewColumn } from 'vs/workbench/common/editor';
|
import { editorGroupToViewColumn } from 'vs/workbench/common/editor';
|
||||||
import { getNotebookEditorFromEditorPane, IActiveNotebookEditor, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
import { getNotebookEditorFromEditorPane, IActiveNotebookEditor, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||||
import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService';
|
import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService';
|
||||||
@@ -68,7 +68,7 @@ class NotebookAndEditorState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@extHostCustomer
|
// @extHostCustomer {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
export class MainThreadNotebooksAndEditors {
|
export class MainThreadNotebooksAndEditors {
|
||||||
|
|
||||||
private readonly _onDidAddNotebooks = new Emitter<NotebookTextModel[]>();
|
private readonly _onDidAddNotebooks = new Emitter<NotebookTextModel[]>();
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ import { combinedDisposable, DisposableStore, IDisposable } from 'vs/base/common
|
|||||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
// import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||||
import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService';
|
import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/notebookEditorService';
|
||||||
import { INotebookKernel, INotebookKernelChangeEvent } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
import { INotebookKernel, INotebookKernelChangeEvent } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||||
import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
|
import { INotebookKernelService } from 'vs/workbench/contrib/notebook/common/notebookKernelService';
|
||||||
import { ExtHostContext, ExtHostNotebookKernelsShape, IExtHostContext, INotebookKernelDto2, MainContext, MainThreadNotebookKernelsShape } from '../common/extHost.protocol';
|
import { ExtHostContext, ExtHostNotebookKernelsShape, IExtHostContext, INotebookKernelDto2, MainThreadNotebookKernelsShape } from '../common/extHost.protocol';// {{SQL CARBON EDIT}} Remove MainContext
|
||||||
|
|
||||||
abstract class MainThreadKernel implements INotebookKernel {
|
abstract class MainThreadKernel implements INotebookKernel {
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ abstract class MainThreadKernel implements INotebookKernel {
|
|||||||
abstract cancelNotebookCellExecution(uri: URI, cellHandles: number[]): Promise<void>;
|
abstract cancelNotebookCellExecution(uri: URI, cellHandles: number[]): Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@extHostNamedCustomer(MainContext.MainThreadNotebookKernels)
|
// @extHostNamedCustomer(MainContext.MainThreadNotebookKernels) {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
export class MainThreadNotebookKernels implements MainThreadNotebookKernelsShape {
|
export class MainThreadNotebookKernels implements MainThreadNotebookKernelsShape {
|
||||||
|
|
||||||
private readonly _editors = new Map<INotebookEditor, IDisposable>();
|
private readonly _editors = new Map<INotebookEditor, IDisposable>();
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
import { Disposable } from 'vs/base/common/lifecycle';
|
import { Disposable } from 'vs/base/common/lifecycle';
|
||||||
import { ExtHostContext, ExtHostNotebookRenderersShape, IExtHostContext, MainContext, MainThreadNotebookRenderersShape } from 'vs/workbench/api/common/extHost.protocol';
|
import { ExtHostContext, ExtHostNotebookRenderersShape, IExtHostContext, MainThreadNotebookRenderersShape } from 'vs/workbench/api/common/extHost.protocol'; // {{SQL CARBON EDIT}} Remove MainContext
|
||||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
// import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; {{SQL CARBON EDIT}}
|
||||||
import { INotebookRendererMessagingService } from 'vs/workbench/contrib/notebook/common/notebookRendererMessagingService';
|
import { INotebookRendererMessagingService } from 'vs/workbench/contrib/notebook/common/notebookRendererMessagingService';
|
||||||
|
|
||||||
@extHostNamedCustomer(MainContext.MainThreadNotebookRenderers)
|
// @extHostNamedCustomer(MainContext.MainThreadNotebookRenderers) {{SQL CARBON EDIT}}
|
||||||
export class MainThreadNotebookRenderers extends Disposable implements MainThreadNotebookRenderersShape {
|
export class MainThreadNotebookRenderers extends Disposable implements MainThreadNotebookRenderersShape {
|
||||||
private readonly proxy: ExtHostNotebookRenderersShape;
|
private readonly proxy: ExtHostNotebookRenderersShape;
|
||||||
|
|
||||||
|
|||||||
@@ -58,19 +58,19 @@ import { getRemoteName } from 'vs/platform/remote/common/remoteHosts';
|
|||||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||||
import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations';
|
import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations';
|
||||||
import { IExtHostTask } from 'vs/workbench/api/common/extHostTask';
|
import { IExtHostTask } from 'vs/workbench/api/common/extHostTask';
|
||||||
// import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; {{SQL CARBON EDIT}}
|
// import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService'; {{SQL CARBON EDIT}} remove debug service
|
||||||
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
|
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
|
||||||
import { ILogService } from 'vs/platform/log/common/log';
|
import { ILogService } from 'vs/platform/log/common/log';
|
||||||
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
|
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
|
||||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||||
import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
|
// import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook'; {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
import { ExtHostTheming } from 'vs/workbench/api/common/extHostTheming';
|
import { ExtHostTheming } from 'vs/workbench/api/common/extHostTheming';
|
||||||
import { IExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelService';
|
import { IExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelService';
|
||||||
import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
|
import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
|
||||||
import { ExtHostAuthentication } from 'vs/workbench/api/common/extHostAuthentication';
|
import { ExtHostAuthentication } from 'vs/workbench/api/common/extHostAuthentication';
|
||||||
import { ExtHostTimeline } from 'vs/workbench/api/common/extHostTimeline';
|
import { ExtHostTimeline } from 'vs/workbench/api/common/extHostTimeline';
|
||||||
import { ExtHostNotebookConcatDocument } from 'vs/workbench/api/common/extHostNotebookConcatDocument';
|
// import { ExtHostNotebookConcatDocument } from 'vs/workbench/api/common/extHostNotebookConcatDocument'; {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
|
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
|
||||||
import { IExtHostConsumerFileSystem } from 'vs/workbench/api/common/extHostFileSystemConsumer';
|
import { IExtHostConsumerFileSystem } from 'vs/workbench/api/common/extHostFileSystemConsumer';
|
||||||
import { ExtHostWebviewViews } from 'vs/workbench/api/common/extHostWebviewView';
|
import { ExtHostWebviewViews } from 'vs/workbench/api/common/extHostWebviewView';
|
||||||
@@ -83,13 +83,15 @@ import { ExtHostUriOpeners } from 'vs/workbench/api/common/extHostUriOpener';
|
|||||||
import { IExtHostSecretState } from 'vs/workbench/api/common/exHostSecretState';
|
import { IExtHostSecretState } from 'vs/workbench/api/common/exHostSecretState';
|
||||||
import { IExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs';
|
import { IExtHostEditorTabs } from 'vs/workbench/api/common/extHostEditorTabs';
|
||||||
import { IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry';
|
import { IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry';
|
||||||
import { ExtHostNotebookKernels } from 'vs/workbench/api/common/extHostNotebookKernels';
|
// import { ExtHostNotebookKernels } from 'vs/workbench/api/common/extHostNotebookKernels'; {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
import { TextSearchCompleteMessageType } from 'vs/workbench/services/search/common/searchExtTypes';
|
import { TextSearchCompleteMessageType } from 'vs/workbench/services/search/common/searchExtTypes';
|
||||||
import { ExtHostNotebookRenderers } from 'vs/workbench/api/common/extHostNotebookRenderers';
|
// import { ExtHostNotebookRenderers } from 'vs/workbench/api/common/extHostNotebookRenderers'; {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
import { Schemas } from 'vs/base/common/network';
|
import { Schemas } from 'vs/base/common/network';
|
||||||
import { matchesScheme } from 'vs/platform/opener/common/opener';
|
import { matchesScheme } from 'vs/platform/opener/common/opener';
|
||||||
import { ExtHostNotebookEditors } from 'vs/workbench/api/common/extHostNotebookEditors';
|
// import { ExtHostNotebookEditors } from 'vs/workbench/api/common/extHostNotebookEditors'; {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
import { ExtHostNotebookDocuments } from 'vs/workbench/api/common/extHostNotebookDocuments';
|
// import { ExtHostNotebookDocuments } from 'vs/workbench/api/common/extHostNotebookDocuments'; {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
|
import { ExtHostNotebook } from 'sql/workbench/api/common/extHostNotebook';
|
||||||
|
import { functionalityNotSupportedError } from 'sql/base/common/locConstants';
|
||||||
|
|
||||||
export interface IExtensionApiFactory {
|
export interface IExtensionApiFactory {
|
||||||
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode;
|
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode;
|
||||||
@@ -98,7 +100,7 @@ export interface IExtensionApiFactory {
|
|||||||
/**
|
/**
|
||||||
* This method instantiates and returns the extension API surface
|
* This method instantiates and returns the extension API surface
|
||||||
*/
|
*/
|
||||||
export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): IExtensionApiFactory {
|
export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor, extHostNotebook: ExtHostNotebook): IExtensionApiFactory { // {{SQL CARBON EDIT}} Add ExtHostNotebook
|
||||||
|
|
||||||
// services
|
// services
|
||||||
const initData = accessor.get(IExtHostInitDataService);
|
const initData = accessor.get(IExtHostInitDataService);
|
||||||
@@ -147,11 +149,13 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||||||
const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors));
|
const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors));
|
||||||
const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService));
|
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 extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadBulkEdits)));
|
||||||
|
/* {{SQL CARBON EDIT }} Disable VS Code notebooks
|
||||||
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors, extHostDocuments, extensionStoragePaths));
|
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors, extHostDocuments, extensionStoragePaths));
|
||||||
const extHostNotebookDocuments = rpcProtocol.set(ExtHostContext.ExtHostNotebookDocuments, new ExtHostNotebookDocuments(extHostLogService, extHostNotebook));
|
const extHostNotebookDocuments = rpcProtocol.set(ExtHostContext.ExtHostNotebookDocuments, new ExtHostNotebookDocuments(extHostLogService, extHostNotebook));
|
||||||
const extHostNotebookEditors = rpcProtocol.set(ExtHostContext.ExtHostNotebookEditors, new ExtHostNotebookEditors(extHostLogService, rpcProtocol, extHostNotebook));
|
const extHostNotebookEditors = rpcProtocol.set(ExtHostContext.ExtHostNotebookEditors, new ExtHostNotebookEditors(extHostLogService, rpcProtocol, extHostNotebook));
|
||||||
const extHostNotebookKernels = rpcProtocol.set(ExtHostContext.ExtHostNotebookKernels, new ExtHostNotebookKernels(rpcProtocol, initData, extHostNotebook, extHostLogService));
|
const extHostNotebookKernels = rpcProtocol.set(ExtHostContext.ExtHostNotebookKernels, new ExtHostNotebookKernels(rpcProtocol, initData, extHostNotebook, extHostLogService));
|
||||||
const extHostNotebookRenderers = rpcProtocol.set(ExtHostContext.ExtHostNotebookRenderers, new ExtHostNotebookRenderers(rpcProtocol, extHostNotebook));
|
const extHostNotebookRenderers = rpcProtocol.set(ExtHostContext.ExtHostNotebookRenderers, new ExtHostNotebookRenderers(rpcProtocol, extHostNotebook));
|
||||||
|
*/
|
||||||
const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors));
|
const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors));
|
||||||
const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService));
|
const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService));
|
||||||
const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, initData));
|
const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, initData));
|
||||||
@@ -176,8 +180,15 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||||||
|
|
||||||
// Check that no named customers are missing
|
// Check that no named customers are missing
|
||||||
// {{SQL CARBON EDIT}} filter out the services we don't expose
|
// {{SQL CARBON EDIT}} filter out the services we don't expose
|
||||||
const filtered: ProxyIdentifier<any>[] = [ExtHostContext.ExtHostDebugService];
|
const filteredProxies: Set<ProxyIdentifier<any>> = new Set([
|
||||||
const expected: ProxyIdentifier<any>[] = values(ExtHostContext).filter(v => !filtered.find(x => x === v));
|
ExtHostContext.ExtHostDebugService,
|
||||||
|
ExtHostContext.ExtHostNotebook,
|
||||||
|
ExtHostContext.ExtHostNotebookDocuments,
|
||||||
|
ExtHostContext.ExtHostNotebookEditors,
|
||||||
|
ExtHostContext.ExtHostNotebookKernels,
|
||||||
|
ExtHostContext.ExtHostNotebookRenderers
|
||||||
|
]);
|
||||||
|
const expected: ProxyIdentifier<any>[] = values(ExtHostContext).filter(v => !filteredProxies.has(v));
|
||||||
|
|
||||||
rpcProtocol.assertRegistered(expected);
|
rpcProtocol.assertRegistered(expected);
|
||||||
|
|
||||||
@@ -718,32 +729,46 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||||||
return extHostWebviewViews.registerWebviewViewProvider(extension, viewId, provider, options?.webviewOptions);
|
return extHostWebviewViews.registerWebviewViewProvider(extension, viewId, provider, options?.webviewOptions);
|
||||||
},
|
},
|
||||||
get activeNotebookEditor(): vscode.NotebookEditor | undefined {
|
get activeNotebookEditor(): vscode.NotebookEditor | undefined {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebook.activeNotebookEditor;
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebook.activeNotebookEditor;
|
||||||
},
|
},
|
||||||
onDidChangeActiveNotebookEditor(listener, thisArgs?, disposables?) {
|
onDidChangeActiveNotebookEditor(listener, thisArgs?, disposables?) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebook.onDidChangeActiveNotebookEditor(listener, thisArgs, disposables);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebook.onDidChangeActiveNotebookEditor(listener, thisArgs, disposables);
|
||||||
},
|
},
|
||||||
get visibleNotebookEditors() {
|
get visibleNotebookEditors() {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebook.visibleNotebookEditors;
|
return undefined;
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebook.visibleNotebookEditors;
|
||||||
},
|
},
|
||||||
get onDidChangeVisibleNotebookEditors() {
|
get onDidChangeVisibleNotebookEditors() {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebook.onDidChangeVisibleNotebookEditors;
|
return undefined;
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebook.onDidChangeVisibleNotebookEditors;
|
||||||
},
|
},
|
||||||
onDidChangeNotebookEditorSelection(listener, thisArgs?, disposables?) {
|
onDidChangeNotebookEditorSelection(listener, thisArgs?, disposables?) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebookEditors.onDidChangeNotebookEditorSelection(listener, thisArgs, disposables);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebookEditors.onDidChangeNotebookEditorSelection(listener, thisArgs, disposables);
|
||||||
},
|
},
|
||||||
onDidChangeNotebookEditorVisibleRanges(listener, thisArgs?, disposables?) {
|
onDidChangeNotebookEditorVisibleRanges(listener, thisArgs?, disposables?) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebookEditors.onDidChangeNotebookEditorVisibleRanges(listener, thisArgs, disposables);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebookEditors.onDidChangeNotebookEditorVisibleRanges(listener, thisArgs, disposables);
|
||||||
},
|
},
|
||||||
showNotebookDocument(uriOrDocument, options?) {
|
showNotebookDocument(uriOrDocument, options?) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebook.showNotebookDocument(uriOrDocument, options);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebook.showNotebookDocument(uriOrDocument, options);
|
||||||
},
|
},
|
||||||
registerExternalUriOpener(id: string, opener: vscode.ExternalUriOpener, metadata: vscode.ExternalUriOpenerMetadata) {
|
registerExternalUriOpener(id: string, opener: vscode.ExternalUriOpener, metadata: vscode.ExternalUriOpenerMetadata) {
|
||||||
checkProposedApiEnabled(extension);
|
checkProposedApiEnabled(extension);
|
||||||
@@ -872,32 +897,42 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||||||
return extHostDocumentSaveParticipant.getOnWillSaveTextDocumentEvent(extension)(listener, thisArgs, disposables);
|
return extHostDocumentSaveParticipant.getOnWillSaveTextDocumentEvent(extension)(listener, thisArgs, disposables);
|
||||||
},
|
},
|
||||||
get notebookDocuments(): vscode.NotebookDocument[] {
|
get notebookDocuments(): vscode.NotebookDocument[] {
|
||||||
return extHostNotebook.notebookDocuments.map(d => d.apiNotebook);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// return extHostNotebook.notebookDocuments.map(d => d.apiNotebook);
|
||||||
},
|
},
|
||||||
async openNotebookDocument(uriOrType?: URI | string, content?: vscode.NotebookData) {
|
async openNotebookDocument(uriOrType?: URI | string, content?: vscode.NotebookData) {
|
||||||
let uri: URI;
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
if (URI.isUri(uriOrType)) {
|
throw new Error(functionalityNotSupportedError);
|
||||||
uri = uriOrType;
|
// let uri: URI;
|
||||||
await extHostNotebook.openNotebookDocument(uriOrType);
|
// if (URI.isUri(uriOrType)) {
|
||||||
} else if (typeof uriOrType === 'string') {
|
// uri = uriOrType;
|
||||||
uri = URI.revive(await extHostNotebook.createNotebookDocument({ viewType: uriOrType, content }));
|
// await extHostNotebook.openNotebookDocument(uriOrType);
|
||||||
} else {
|
// } else if (typeof uriOrType === 'string') {
|
||||||
throw new Error('Invalid arguments');
|
// uri = URI.revive(await extHostNotebook.createNotebookDocument({ viewType: uriOrType, content }));
|
||||||
}
|
// } else {
|
||||||
return extHostNotebook.getNotebookDocument(uri).apiNotebook;
|
// throw new Error('Invalid arguments');
|
||||||
|
// }
|
||||||
|
// return extHostNotebook.getNotebookDocument(uri).apiNotebook;
|
||||||
},
|
},
|
||||||
get onDidOpenNotebookDocument(): Event<vscode.NotebookDocument> {
|
get onDidOpenNotebookDocument(): Event<vscode.NotebookDocument> {
|
||||||
return extHostNotebook.onDidOpenNotebookDocument;
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// return extHostNotebook.onDidOpenNotebookDocument;
|
||||||
},
|
},
|
||||||
get onDidCloseNotebookDocument(): Event<vscode.NotebookDocument> {
|
get onDidCloseNotebookDocument(): Event<vscode.NotebookDocument> {
|
||||||
return extHostNotebook.onDidCloseNotebookDocument;
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// return extHostNotebook.onDidCloseNotebookDocument;
|
||||||
},
|
},
|
||||||
registerNotebookSerializer(viewType: string, serializer: vscode.NotebookSerializer, options?: vscode.NotebookDocumentContentOptions, registration?: vscode.NotebookRegistrationData) {
|
registerNotebookSerializer(viewType: string, serializer: vscode.NotebookSerializer, options?: vscode.NotebookDocumentContentOptions, registration?: vscode.NotebookRegistrationData) {
|
||||||
return extHostNotebook.registerNotebookSerializer(extension, viewType, serializer, options, extension.enableProposedApi ? registration : undefined);
|
return extHostNotebook.registerNotebookSerializer(viewType, serializer, options, extension.enableProposedApi ? registration : undefined);
|
||||||
},
|
},
|
||||||
registerNotebookContentProvider: (viewType: string, provider: vscode.NotebookContentProvider, options?: vscode.NotebookDocumentContentOptions, registration?: vscode.NotebookRegistrationData) => {
|
registerNotebookContentProvider: (viewType: string, provider: vscode.NotebookContentProvider, options?: vscode.NotebookDocumentContentOptions, registration?: vscode.NotebookRegistrationData) => {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebook.registerNotebookContentProvider(extension, viewType, provider, options, extension.enableProposedApi ? registration : undefined);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebook.registerNotebookContentProvider(extension, viewType, provider, options, extension.enableProposedApi ? registration : undefined);
|
||||||
},
|
},
|
||||||
onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
|
onDidChangeConfiguration: (listener: (_: any) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) => {
|
||||||
return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables);
|
return configProvider.onDidChangeConfiguration(listener, thisArgs, disposables);
|
||||||
@@ -1110,46 +1145,66 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
|||||||
// namespace: notebook
|
// namespace: notebook
|
||||||
const notebooks: typeof vscode.notebooks = {
|
const notebooks: typeof vscode.notebooks = {
|
||||||
createNotebookController(id: string, notebookType: string, label: string, handler?, rendererScripts?: vscode.NotebookRendererScript[]) {
|
createNotebookController(id: string, notebookType: string, label: string, handler?, rendererScripts?: vscode.NotebookRendererScript[]) {
|
||||||
return extHostNotebookKernels.createNotebookController(extension, id, notebookType, label, handler, extension.enableProposedApi ? rendererScripts : undefined);
|
return extHostNotebook.createNotebookController(extension, id, notebookType, label, handler, extension.enableProposedApi ? rendererScripts : undefined);
|
||||||
},
|
},
|
||||||
registerNotebookCellStatusBarItemProvider: (notebookType: string, provider: vscode.NotebookCellStatusBarItemProvider) => {
|
registerNotebookCellStatusBarItemProvider: (notebookType: string, provider: vscode.NotebookCellStatusBarItemProvider) => {
|
||||||
return extHostNotebook.registerNotebookCellStatusBarItemProvider(extension, notebookType, provider);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// return extHostNotebook.registerNotebookCellStatusBarItemProvider(extension, notebookType, provider);
|
||||||
},
|
},
|
||||||
get onDidSaveNotebookDocument(): Event<vscode.NotebookDocument> {
|
get onDidSaveNotebookDocument(): Event<vscode.NotebookDocument> {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebookDocuments.onDidSaveNotebookDocument;
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebookDocuments.onDidSaveNotebookDocument;
|
||||||
},
|
},
|
||||||
createNotebookEditorDecorationType(options: vscode.NotebookDecorationRenderOptions): vscode.NotebookEditorDecorationType {
|
createNotebookEditorDecorationType(options: vscode.NotebookDecorationRenderOptions): vscode.NotebookEditorDecorationType {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebookEditors.createNotebookEditorDecorationType(options);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebookEditors.createNotebookEditorDecorationType(options);
|
||||||
},
|
},
|
||||||
createRendererMessaging(rendererId) {
|
createRendererMessaging(rendererId) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebookRenderers.createRendererMessaging(rendererId);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebookRenderers.createRendererMessaging(rendererId);
|
||||||
},
|
},
|
||||||
onDidChangeNotebookDocumentMetadata(listener, thisArgs?, disposables?) {
|
onDidChangeNotebookDocumentMetadata(listener, thisArgs?, disposables?) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebookDocuments.onDidChangeNotebookDocumentMetadata(listener, thisArgs, disposables);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebookDocuments.onDidChangeNotebookDocumentMetadata(listener, thisArgs, disposables);
|
||||||
},
|
},
|
||||||
onDidChangeNotebookCells(listener, thisArgs?, disposables?) {
|
onDidChangeNotebookCells(listener, thisArgs?, disposables?) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebook.onDidChangeNotebookCells(listener, thisArgs, disposables);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebook.onDidChangeNotebookCells(listener, thisArgs, disposables);
|
||||||
},
|
},
|
||||||
onDidChangeNotebookCellExecutionState(listener, thisArgs?, disposables?) {
|
onDidChangeNotebookCellExecutionState(listener, thisArgs?, disposables?) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebook.onDidChangeNotebookCellExecutionState(listener, thisArgs, disposables);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebook.onDidChangeNotebookCellExecutionState(listener, thisArgs, disposables);
|
||||||
},
|
},
|
||||||
onDidChangeCellOutputs(listener, thisArgs?, disposables?) {
|
onDidChangeCellOutputs(listener, thisArgs?, disposables?) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebook.onDidChangeCellOutputs(listener, thisArgs, disposables);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebook.onDidChangeCellOutputs(listener, thisArgs, disposables);
|
||||||
},
|
},
|
||||||
onDidChangeCellMetadata(listener, thisArgs?, disposables?) {
|
onDidChangeCellMetadata(listener, thisArgs?, disposables?) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return extHostNotebook.onDidChangeCellMetadata(listener, thisArgs, disposables);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return extHostNotebook.onDidChangeCellMetadata(listener, thisArgs, disposables);
|
||||||
},
|
},
|
||||||
createConcatTextDocument(notebook, selector) {
|
createConcatTextDocument(notebook, selector) {
|
||||||
checkProposedApiEnabled(extension);
|
// {{SQL CARBON EDIT}} Disable VS Code notebooks
|
||||||
return new ExtHostNotebookConcatDocument(extHostNotebook, extHostDocuments, notebook, selector);
|
throw new Error(functionalityNotSupportedError);
|
||||||
|
// checkProposedApiEnabled(extension);
|
||||||
|
// return new ExtHostNotebookConcatDocument(extHostNotebook, extHostDocuments, notebook, selector);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
|||||||
import * as nls from 'vs/nls';
|
import * as nls from 'vs/nls';
|
||||||
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||||
import { NotebookEditorPriority, NotebookRendererEntrypoint, RendererMessagingSpec } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
import { NotebookEditorPriority, NotebookRendererEntrypoint, RendererMessagingSpec } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||||
|
import { Registry } from 'vs/platform/registry/common/platform'; // {{SQL CARBON EDIT}} Register notebooks in SQL code instead
|
||||||
|
import { INotebookProviderRegistry, NotebookProviderRegistryId, ProviderDescriptionRegistration } from 'sql/workbench/services/notebook/common/notebookRegistry'; // {{SQL CARBON EDIT}} Register notebooks in SQL code instead
|
||||||
|
|
||||||
namespace NotebookEditorContribution {
|
namespace NotebookEditorContribution {
|
||||||
export const type = 'type';
|
export const type = 'type';
|
||||||
@@ -185,6 +187,31 @@ export const notebooksExtensionPoint = ExtensionsRegistry.registerExtensionPoint
|
|||||||
jsonSchema: notebookProviderContribution
|
jsonSchema: notebookProviderContribution
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// {{SQL CARBON EDIT}} Convert VSCode notebook registrations into ADS equivalents
|
||||||
|
const adsNotebookRegistry = Registry.as<INotebookProviderRegistry>(NotebookProviderRegistryId);
|
||||||
|
notebooksExtensionPoint.setHandler(extensions => {
|
||||||
|
for (let extension of extensions) {
|
||||||
|
for (const notebookContribution of extension.value) {
|
||||||
|
// Remove any leading regex characters from the filename pattern
|
||||||
|
let extensions = notebookContribution.selector?.filter(ext => ext?.filenamePattern?.length > 0)
|
||||||
|
.map(s => {
|
||||||
|
let lastDotPosition = s.filenamePattern?.lastIndexOf('.');
|
||||||
|
if (lastDotPosition >= 0) {
|
||||||
|
return s.filenamePattern.slice(lastDotPosition);
|
||||||
|
}
|
||||||
|
return s.filenamePattern;
|
||||||
|
});
|
||||||
|
|
||||||
|
let adsProvider: ProviderDescriptionRegistration = {
|
||||||
|
provider: notebookContribution.type,
|
||||||
|
fileExtensions: extensions ?? [],
|
||||||
|
standardKernels: [] // Kernels get added later when a NotebookController is created for this provider
|
||||||
|
};
|
||||||
|
adsNotebookRegistry.registerProviderDescription(adsProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookRendererContribution[]>(
|
export const notebookRendererExtensionPoint = ExtensionsRegistry.registerExtensionPoint<INotebookRendererContribution[]>(
|
||||||
{
|
{
|
||||||
extensionPoint: 'notebookRenderer',
|
extensionPoint: 'notebookRenderer',
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { URI } from 'vs/base/common/uri';
|
|||||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||||
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
|
||||||
import { localize } from 'vs/nls';
|
// import { localize } from 'vs/nls'; {{SQL CARBON EDIT}} Notebook registration handled in SQL code
|
||||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||||
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||||
@@ -27,12 +27,12 @@ import { NotebookExtensionDescription } from 'vs/workbench/api/common/extHost.pr
|
|||||||
import { IEditorInput } from 'vs/workbench/common/editor';
|
import { IEditorInput } from 'vs/workbench/common/editor';
|
||||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||||
import { Memento } from 'vs/workbench/common/memento';
|
import { Memento } from 'vs/workbench/common/memento';
|
||||||
import { INotebookEditorContribution, notebooksExtensionPoint, notebookRendererExtensionPoint } from 'vs/workbench/contrib/notebook/browser/extensionPoint';
|
import { notebookRendererExtensionPoint } from 'vs/workbench/contrib/notebook/browser/extensionPoint'; // {{SQL CARBON EDIT}} Remove INotebookEditorContribution, notebooksExtensionPoint
|
||||||
import { INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
import { INotebookEditorOptions } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||||
import { NotebookDiffEditorInput } from 'vs/workbench/contrib/notebook/browser/notebookDiffEditorInput';
|
import { NotebookDiffEditorInput } from 'vs/workbench/contrib/notebook/browser/notebookDiffEditorInput';
|
||||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||||
import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, BUILTIN_RENDERER_ID, CellUri, DisplayOrderKey, INotebookExclusiveDocumentFilter, INotebookContributionData, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, IOutputDto, mimeTypeIsAlwaysSecure, mimeTypeSupportedByCore, NotebookDataDto, NotebookEditorPriority, NotebookRendererMatch, NotebookTextDiffEditorPreview, RENDERER_NOT_AVAILABLE, sortMimeTypes, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, BUILTIN_RENDERER_ID, CellUri, DisplayOrderKey, INotebookExclusiveDocumentFilter, INotebookContributionData, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, IOutputDto, mimeTypeIsAlwaysSecure, mimeTypeSupportedByCore, NotebookDataDto, NotebookRendererMatch, NotebookTextDiffEditorPreview, RENDERER_NOT_AVAILABLE, sortMimeTypes, TransientOptions } from 'vs/workbench/contrib/notebook/common/notebookCommon'; // {{SQL CARBON EDIT}} Remove NotebookEditorPriority
|
||||||
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
|
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';
|
||||||
import { updateEditorTopPadding } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
import { updateEditorTopPadding } from 'vs/workbench/contrib/notebook/common/notebookOptions';
|
||||||
import { NotebookOutputRendererInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer';
|
import { NotebookOutputRendererInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer';
|
||||||
@@ -40,7 +40,7 @@ import { NotebookEditorDescriptor, NotebookProviderInfo } from 'vs/workbench/con
|
|||||||
import { ComplexNotebookProviderInfo, INotebookContentProvider, INotebookSerializer, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService';
|
import { ComplexNotebookProviderInfo, INotebookContentProvider, INotebookSerializer, INotebookService, SimpleNotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||||
import { ContributedEditorPriority, DiffEditorInputFactoryFunction, EditorInputFactoryFunction, IEditorOverrideService, IEditorType } from 'vs/workbench/services/editor/common/editorOverrideService';
|
import { ContributedEditorPriority, DiffEditorInputFactoryFunction, EditorInputFactoryFunction, IEditorOverrideService, IEditorType } from 'vs/workbench/services/editor/common/editorOverrideService';
|
||||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||||
import { IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
// import { IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry'; {{SQL CARBON EDIT}} Notebook registration handled in SQL code
|
||||||
|
|
||||||
export class NotebookProviderInfoStore extends Disposable {
|
export class NotebookProviderInfoStore extends Disposable {
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ export class NotebookProviderInfoStore extends Disposable {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
notebooksExtensionPoint.setHandler(extensions => this._setupHandler(extensions));
|
// notebooksExtensionPoint.setHandler(extensions => this._setupHandler(extensions)); {{SQL CARBON EDIT}} Notebook registration handled in SQL code
|
||||||
}
|
}
|
||||||
|
|
||||||
override dispose(): void {
|
override dispose(): void {
|
||||||
@@ -88,52 +88,53 @@ export class NotebookProviderInfoStore extends Disposable {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _setupHandler(extensions: readonly IExtensionPointUser<INotebookEditorContribution[]>[]) {
|
// {{SQL CARBON EDIT}} Notebook registration handled in SQL code
|
||||||
this._handled = true;
|
// private _setupHandler(extensions: readonly IExtensionPointUser<INotebookEditorContribution[]>[]) {
|
||||||
this._clear();
|
// this._handled = true;
|
||||||
|
// this._clear();
|
||||||
|
|
||||||
for (const extension of extensions) {
|
// for (const extension of extensions) {
|
||||||
for (const notebookContribution of extension.value) {
|
// for (const notebookContribution of extension.value) {
|
||||||
|
|
||||||
if (!notebookContribution.type) {
|
// if (!notebookContribution.type) {
|
||||||
extension.collector.error(`Notebook does not specify type-property`);
|
// extension.collector.error(`Notebook does not specify type-property`);
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (this.get(notebookContribution.type)) {
|
// if (this.get(notebookContribution.type)) {
|
||||||
extension.collector.error(`Notebook type '${notebookContribution.type}' already used`);
|
// extension.collector.error(`Notebook type '${notebookContribution.type}' already used`);
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
|
|
||||||
this.add(new NotebookProviderInfo({
|
// this.add(new NotebookProviderInfo({
|
||||||
extension: extension.description.identifier,
|
// extension: extension.description.identifier,
|
||||||
id: notebookContribution.type,
|
// id: notebookContribution.type,
|
||||||
displayName: notebookContribution.displayName,
|
// displayName: notebookContribution.displayName,
|
||||||
selectors: notebookContribution.selector || [],
|
// selectors: notebookContribution.selector || [],
|
||||||
priority: this._convertPriority(notebookContribution.priority),
|
// priority: this._convertPriority(notebookContribution.priority),
|
||||||
providerDisplayName: extension.description.isBuiltin ? localize('builtinProviderDisplayName', "Built-in") : extension.description.displayName || extension.description.identifier.value,
|
// providerDisplayName: extension.description.isBuiltin ? localize('builtinProviderDisplayName', "Built-in") : extension.description.displayName || extension.description.identifier.value,
|
||||||
exclusive: false
|
// exclusive: false
|
||||||
}));
|
// }));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
const mementoObject = this._memento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
|
// const mementoObject = this._memento.getMemento(StorageScope.GLOBAL, StorageTarget.MACHINE);
|
||||||
mementoObject[NotebookProviderInfoStore.CUSTOM_EDITORS_ENTRY_ID] = Array.from(this._contributedEditors.values());
|
// mementoObject[NotebookProviderInfoStore.CUSTOM_EDITORS_ENTRY_ID] = Array.from(this._contributedEditors.values());
|
||||||
this._memento.saveMemento();
|
// this._memento.saveMemento();
|
||||||
}
|
// }
|
||||||
|
|
||||||
private _convertPriority(priority?: string) {
|
// private _convertPriority(priority?: string) {
|
||||||
if (!priority) {
|
// if (!priority) {
|
||||||
return ContributedEditorPriority.default;
|
// return ContributedEditorPriority.default;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (priority === NotebookEditorPriority.default) {
|
// if (priority === NotebookEditorPriority.default) {
|
||||||
return ContributedEditorPriority.default;
|
// return ContributedEditorPriority.default;
|
||||||
}
|
// }
|
||||||
|
|
||||||
return ContributedEditorPriority.option;
|
// return ContributedEditorPriority.option;
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
private _registerContributionPoint(notebookProviderInfo: NotebookProviderInfo): IDisposable {
|
private _registerContributionPoint(notebookProviderInfo: NotebookProviderInfo): IDisposable {
|
||||||
|
|
||||||
|
|||||||
@@ -213,7 +213,14 @@ export class ExtensionHostManager extends Disposable {
|
|||||||
|
|
||||||
// Check that no named customers are missing
|
// Check that no named customers are missing
|
||||||
// {{SQL CARBON EDIT}} filter out services we don't expose
|
// {{SQL CARBON EDIT}} filter out services we don't expose
|
||||||
const filtered: ProxyIdentifier<any>[] = [MainContext.MainThreadDebugService];
|
const filtered: ProxyIdentifier<any>[] = [
|
||||||
|
MainContext.MainThreadDebugService,
|
||||||
|
MainContext.MainThreadNotebook,
|
||||||
|
MainContext.MainThreadNotebookDocuments,
|
||||||
|
MainContext.MainThreadNotebookEditors,
|
||||||
|
MainContext.MainThreadNotebookKernels,
|
||||||
|
MainContext.MainThreadNotebookRenderers
|
||||||
|
];
|
||||||
const expected: ProxyIdentifier<any>[] = Object.keys(MainContext).map((key) => (<any>MainContext)[key]).filter(v => !filtered.some(x => x === v));
|
const expected: ProxyIdentifier<any>[] = Object.keys(MainContext).map((key) => (<any>MainContext)[key]).filter(v => !filtered.some(x => x === v));
|
||||||
this._rpcProtocol.assertRegistered(expected);
|
this._rpcProtocol.assertRegistered(expected);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user