mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-03 09:35:40 -05:00
Merge from vscode 7653d836944892f83ce9e1f95c1204bafa1aec31
This commit is contained in:
@@ -8,7 +8,7 @@ import { MainContext, MainThreadNotebookShape, NotebookExtensionDescription, IEx
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { INotebookService, IMainNotebookController } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
import { INotebookTextModel, INotebookMimeTypeSelector, NOTEBOOK_DISPLAY_ORDER, NotebookCellOutputsSplice, CellKind, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookTextModel, INotebookMimeTypeSelector, NOTEBOOK_DISPLAY_ORDER, NotebookCellOutputsSplice, NotebookDocumentMetadata, NotebookCellMetadata, ICellEditOperation, ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, CellEditType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
@@ -84,7 +84,9 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
||||
|
||||
registerListeners() {
|
||||
this._register(this._notebookService.onDidChangeActiveEditor(e => {
|
||||
this._proxy.$updateActiveEditor(e.viewType, e.uri);
|
||||
this._proxy.$acceptDocumentAndEditorsDelta({
|
||||
newActiveEditor: e.uri
|
||||
});
|
||||
}));
|
||||
|
||||
const updateOrder = () => {
|
||||
@@ -129,16 +131,6 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
||||
return;
|
||||
}
|
||||
|
||||
async $createNotebookDocument(handle: number, viewType: string, resource: UriComponents): Promise<void> {
|
||||
let controller = this._notebookProviders.get(viewType);
|
||||
|
||||
if (controller) {
|
||||
controller.createNotebookDocument(handle, viewType, resource);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
async $updateNotebookLanguages(viewType: string, resource: UriComponents, languages: string[]): Promise<void> {
|
||||
let controller = this._notebookProviders.get(viewType);
|
||||
|
||||
@@ -163,11 +155,6 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
||||
}
|
||||
}
|
||||
|
||||
async resolveNotebook(viewType: string, uri: URI): Promise<number | undefined> {
|
||||
let handle = await this._proxy.$resolveNotebook(viewType, uri);
|
||||
return handle;
|
||||
}
|
||||
|
||||
async $spliceNotebookCellOutputs(viewType: string, resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[], renderers: number[]): Promise<void> {
|
||||
let controller = this._notebookProviders.get(viewType);
|
||||
controller?.spliceNotebookCellOutputs(resource, cellHandle, splices, renderers);
|
||||
@@ -195,6 +182,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
||||
|
||||
export class MainThreadNotebookController implements IMainNotebookController {
|
||||
private _mapping: Map<string, MainThreadNotebookDocument> = new Map();
|
||||
static documentHandle: number = 0;
|
||||
|
||||
constructor(
|
||||
private readonly _proxy: ExtHostNotebookShape,
|
||||
@@ -203,26 +191,44 @@ export class MainThreadNotebookController implements IMainNotebookController {
|
||||
) {
|
||||
}
|
||||
|
||||
async resolveNotebook(viewType: string, uri: URI): Promise<NotebookTextModel | undefined> {
|
||||
// TODO: resolve notebook should wait for all notebook document destory operations to finish.
|
||||
async createNotebook(viewType: string, uri: URI, forBackup: boolean, forceReload: boolean): Promise<NotebookTextModel | undefined> {
|
||||
let mainthreadNotebook = this._mapping.get(URI.from(uri).toString());
|
||||
|
||||
if (mainthreadNotebook) {
|
||||
if (forceReload) {
|
||||
const data = await this._proxy.$resolveNotebookData(viewType, uri);
|
||||
if (!data) {
|
||||
return undefined; // {{SQL CARBON EDIT}}
|
||||
}
|
||||
|
||||
mainthreadNotebook.textModel.languages = data.languages;
|
||||
mainthreadNotebook.textModel.metadata = data.metadata;
|
||||
mainthreadNotebook.textModel.applyEdit(mainthreadNotebook.textModel.versionId, [
|
||||
{ editType: CellEditType.Delete, count: mainthreadNotebook.textModel.cells.length, index: 0 },
|
||||
{ editType: CellEditType.Insert, index: 0, cells: data.cells }
|
||||
]);
|
||||
}
|
||||
return mainthreadNotebook.textModel;
|
||||
}
|
||||
|
||||
let notebookHandle = await this._mainThreadNotebook.resolveNotebook(viewType, uri);
|
||||
if (notebookHandle !== undefined) {
|
||||
mainthreadNotebook = this._mapping.get(URI.from(uri).toString());
|
||||
if (mainthreadNotebook && mainthreadNotebook.textModel.cells.length === 0) {
|
||||
// it's empty, we should create an empty template one
|
||||
const mainCell = mainthreadNotebook.textModel.createCellTextModel([''], mainthreadNotebook.textModel.languages.length ? mainthreadNotebook.textModel.languages[0] : '', CellKind.Code, [], undefined);
|
||||
mainthreadNotebook.textModel.insertTemplateCell(mainCell);
|
||||
}
|
||||
return mainthreadNotebook?.textModel;
|
||||
let document = new MainThreadNotebookDocument(this._proxy, MainThreadNotebookController.documentHandle++, viewType, uri);
|
||||
await this.createNotebookDocument(document);
|
||||
|
||||
if (forBackup) {
|
||||
return document.textModel;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
// open notebook document
|
||||
const data = await this._proxy.$resolveNotebookData(viewType, uri);
|
||||
if (!data) {
|
||||
return undefined; // {{SQL CARBON EDIT}}
|
||||
}
|
||||
|
||||
document.textModel.languages = data.languages;
|
||||
document.textModel.metadata = data.metadata;
|
||||
document.textModel.initialize(data!.cells);
|
||||
|
||||
return document.textModel;
|
||||
}
|
||||
|
||||
async tryApplyEdits(resource: UriComponents, modelVersionId: number, edits: ICellEditOperation[], renderers: number[]): Promise<boolean> {
|
||||
@@ -250,12 +256,32 @@ export class MainThreadNotebookController implements IMainNotebookController {
|
||||
this._proxy.$onDidReceiveMessage(uri, message);
|
||||
}
|
||||
|
||||
// Methods for ExtHost
|
||||
async createNotebookDocument(handle: number, viewType: string, resource: UriComponents): Promise<void> {
|
||||
let document = new MainThreadNotebookDocument(this._proxy, handle, viewType, URI.revive(resource));
|
||||
this._mapping.set(URI.revive(resource).toString(), document);
|
||||
async createNotebookDocument(document: MainThreadNotebookDocument): Promise<void> {
|
||||
this._mapping.set(document.uri.toString(), document);
|
||||
|
||||
await this._proxy.$acceptDocumentAndEditorsDelta({
|
||||
addedDocuments: [{
|
||||
viewType: document.viewType,
|
||||
handle: document.handle,
|
||||
uri: document.uri
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
async removeNotebookDocument(notebook: INotebookTextModel): Promise<void> {
|
||||
let document = this._mapping.get(URI.from(notebook.uri).toString());
|
||||
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
|
||||
await this._proxy.$acceptDocumentAndEditorsDelta({ removedDocuments: [notebook.uri] });
|
||||
document.dispose();
|
||||
this._mapping.delete(URI.from(notebook.uri).toString());
|
||||
}
|
||||
|
||||
// Methods for ExtHost
|
||||
|
||||
updateLanguages(resource: UriComponents, languages: string[]) {
|
||||
let document = this._mapping.get(URI.from(resource).toString());
|
||||
document?.textModel.updateLanguages(languages);
|
||||
@@ -280,21 +306,12 @@ export class MainThreadNotebookController implements IMainNotebookController {
|
||||
return this._proxy.$executeNotebook(this._viewType, uri, handle, token);
|
||||
}
|
||||
|
||||
async destoryNotebookDocument(notebook: INotebookTextModel): Promise<void> {
|
||||
let document = this._mapping.get(URI.from(notebook.uri).toString());
|
||||
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
|
||||
let removeFromExtHost = await this._proxy.$destoryNotebookDocument(this._viewType, notebook.uri);
|
||||
if (removeFromExtHost) {
|
||||
document.dispose();
|
||||
this._mapping.delete(URI.from(notebook.uri).toString());
|
||||
}
|
||||
}
|
||||
|
||||
async save(uri: URI, token: CancellationToken): Promise<boolean> {
|
||||
return this._proxy.$saveNotebook(this._viewType, uri, token);
|
||||
}
|
||||
|
||||
async saveAs(uri: URI, target: URI, token: CancellationToken): Promise<boolean> {
|
||||
return this._proxy.$saveNotebookAs(this._viewType, uri, target, token);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -368,6 +368,9 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||
}
|
||||
|
||||
private addViews(extensions: readonly IExtensionPointUser<ViewExtensionPointType>[]): void {
|
||||
const viewIds: Set<string> = new Set<string>();
|
||||
const allViewDescriptors: { views: IViewDescriptor[], viewContainer: ViewContainer }[] = [];
|
||||
|
||||
for (const extension of extensions) {
|
||||
const { value, collector } = extension;
|
||||
|
||||
@@ -386,10 +389,9 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||
collector.warn(localize('ViewContainerDoesnotExist', "View container '{0}' does not exist and all views registered to it will be added to 'Explorer'.", entry.key));
|
||||
}
|
||||
const container = viewContainer || this.getDefaultViewContainer();
|
||||
const viewIds: string[] = [];
|
||||
const viewDescriptors = coalesce(entry.value.map((item, index) => {
|
||||
// validate
|
||||
if (viewIds.indexOf(item.id) !== -1) {
|
||||
if (viewIds.has(item.id)) {
|
||||
collector.error(localize('duplicateView1', "Cannot register multiple views with same id `{0}`", item.id));
|
||||
return null;
|
||||
}
|
||||
@@ -421,12 +423,16 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
|
||||
remoteAuthority: item.remoteName || (<any>item).remoteAuthority // TODO@roblou - delete after remote extensions are updated
|
||||
};
|
||||
|
||||
viewIds.push(viewDescriptor.id);
|
||||
viewIds.add(viewDescriptor.id);
|
||||
return viewDescriptor;
|
||||
}));
|
||||
this.viewsRegistry.registerViews(viewDescriptors, container);
|
||||
|
||||
allViewDescriptors.push({ viewContainer: container, views: viewDescriptors });
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
this.viewsRegistry.registerViews2(allViewDescriptors);
|
||||
}
|
||||
|
||||
private getDefaultViewContainer(): ViewContainer {
|
||||
|
||||
@@ -931,10 +931,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.onDidCloseNotebookDocument;
|
||||
},
|
||||
registerNotebookProvider: (viewType: string, provider: vscode.NotebookProvider) => {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.registerNotebookProvider(extension, viewType, provider);
|
||||
},
|
||||
registerNotebookContentProvider: (viewType: string, provider: vscode.NotebookContentProvider) => {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.registerNotebookContentProvider(extension, viewType, provider);
|
||||
@@ -1015,6 +1011,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
EvaluatableExpression: extHostTypes.EvaluatableExpression,
|
||||
EventEmitter: Emitter,
|
||||
ExtensionKind: extHostTypes.ExtensionKind,
|
||||
ExtensionMode: extHostTypes.ExtensionMode,
|
||||
CustomExecution: extHostTypes.CustomExecution,
|
||||
CustomExecution2: extHostTypes.CustomExecution,
|
||||
FileChangeType: extHostTypes.FileChangeType,
|
||||
|
||||
@@ -51,7 +51,7 @@ import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
|
||||
import { TunnelOptions } from 'vs/platform/remote/common/tunnel';
|
||||
import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor, InternalTimelineOptions } from 'vs/workbench/contrib/timeline/common/timeline';
|
||||
import { revive } from 'vs/base/common/marshalling';
|
||||
import { INotebookMimeTypeSelector, IOutput, INotebookDisplayOrder, NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEvent } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookMimeTypeSelector, IOutput, INotebookDisplayOrder, NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEvent, NotebookDataDto } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CallHierarchyItem } from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
|
||||
import { Dto } from 'vs/base/common/types';
|
||||
import { ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
|
||||
@@ -695,7 +695,6 @@ export interface MainThreadNotebookShape extends IDisposable {
|
||||
$unregisterNotebookProvider(viewType: string): Promise<void>;
|
||||
$registerNotebookRenderer(extension: NotebookExtensionDescription, type: string, selectors: INotebookMimeTypeSelector, handle: number, preloads: UriComponents[]): Promise<void>;
|
||||
$unregisterNotebookRenderer(handle: number): Promise<void>;
|
||||
$createNotebookDocument(handle: number, viewType: string, resource: UriComponents): Promise<void>;
|
||||
$tryApplyEdits(viewType: string, resource: UriComponents, modelVersionId: number, edits: ICellEditOperation[], renderers: number[]): Promise<boolean>;
|
||||
$updateNotebookLanguages(viewType: string, resource: UriComponents, languages: string[]): Promise<void>;
|
||||
$updateNotebookMetadata(viewType: string, resource: UriComponents, metadata: NotebookDocumentMetadata): Promise<void>;
|
||||
@@ -1542,16 +1541,31 @@ export interface INotebookEditorPropertiesChangeData {
|
||||
selections: INotebookSelectionChangeEvent | null;
|
||||
}
|
||||
|
||||
export interface INotebookModelAddedData {
|
||||
uri: UriComponents;
|
||||
handle: number;
|
||||
// versionId: number;
|
||||
viewType: string;
|
||||
}
|
||||
|
||||
export interface INotebookDocumentsAndEditorsDelta {
|
||||
removedDocuments?: UriComponents[];
|
||||
addedDocuments?: INotebookModelAddedData[];
|
||||
// removedEditors?: string[];
|
||||
// addedEditors?: ITextEditorAddData[];
|
||||
newActiveEditor?: UriComponents | null;
|
||||
}
|
||||
|
||||
export interface ExtHostNotebookShape {
|
||||
$resolveNotebook(viewType: string, uri: UriComponents): Promise<number | undefined>;
|
||||
$resolveNotebookData(viewType: string, uri: UriComponents): Promise<NotebookDataDto | undefined>;
|
||||
$executeNotebook(viewType: string, uri: UriComponents, cellHandle: number | undefined, token: CancellationToken): Promise<void>;
|
||||
$saveNotebook(viewType: string, uri: UriComponents, token: CancellationToken): Promise<boolean>;
|
||||
$updateActiveEditor(viewType: string, uri: UriComponents): Promise<void>;
|
||||
$destoryNotebookDocument(viewType: string, uri: UriComponents): Promise<boolean>;
|
||||
$saveNotebookAs(viewType: string, uri: UriComponents, target: UriComponents, token: CancellationToken): Promise<boolean>;
|
||||
$acceptDisplayOrder(displayOrder: INotebookDisplayOrder): void;
|
||||
$onDidReceiveMessage(uri: UriComponents, message: any): void;
|
||||
$acceptModelChanged(uriComponents: UriComponents, event: NotebookCellsChangedEvent): void;
|
||||
$acceptEditorPropertiesChanged(uriComponents: UriComponents, data: INotebookEditorPropertiesChangeData): void;
|
||||
$acceptDocumentAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta): Promise<void>;
|
||||
}
|
||||
|
||||
export interface ExtHostStorageShape {
|
||||
|
||||
@@ -25,7 +25,7 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { ExtensionMemento } from 'vs/workbench/api/common/extHostMemento';
|
||||
import { RemoteAuthorityResolverError } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { RemoteAuthorityResolverError, ExtensionMode } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { ResolvedAuthority, ResolvedOptions, RemoteAuthorityResolverErrorCode } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||
@@ -358,8 +358,12 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
|
||||
|
||||
const globalState = new ExtensionMemento(extensionDescription.identifier.value, true, this._storage);
|
||||
const workspaceState = new ExtensionMemento(extensionDescription.identifier.value, false, this._storage);
|
||||
const extensionMode = extensionDescription.isUnderDevelopment
|
||||
? (this._initData.environment.extensionTestsLocationURI ? ExtensionMode.Test : ExtensionMode.Development)
|
||||
: ExtensionMode.Release;
|
||||
|
||||
this._logService.trace(`ExtensionService#loadExtensionContext ${extensionDescription.identifier.value}`);
|
||||
|
||||
return Promise.all([
|
||||
globalState.whenReady,
|
||||
workspaceState.whenReady,
|
||||
@@ -376,10 +380,11 @@ export abstract class AbstractExtHostExtensionService implements ExtHostExtensio
|
||||
get globalStoragePath() { return that._storagePath.globalValue(extensionDescription); },
|
||||
asAbsolutePath(relativePath: string) { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); },
|
||||
get logPath() { return path.join(that._initData.logsLocation.fsPath, extensionDescription.identifier.value); },
|
||||
get environmentVariableCollection() {
|
||||
get extensionMode() {
|
||||
checkProposedApiEnabled(extensionDescription);
|
||||
return that._extHostTerminalService.getEnvironmentVariableCollection(extensionDescription);
|
||||
}
|
||||
return extensionMode;
|
||||
},
|
||||
get environmentVariableCollection() { return that._extHostTerminalService.getEnvironmentVariableCollection(extensionDescription); }
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,10 +10,10 @@ import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecyc
|
||||
import { ISplice } from 'vs/base/common/sequence';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { CellKind, CellOutputKind, ExtHostNotebookShape, IMainContext, MainContext, MainThreadNotebookShape, NotebookCellOutputsSplice, MainThreadDocumentsShape, INotebookEditorPropertiesChangeData } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { CellKind, CellOutputKind, ExtHostNotebookShape, IMainContext, MainContext, MainThreadNotebookShape, NotebookCellOutputsSplice, MainThreadDocumentsShape, INotebookEditorPropertiesChangeData, INotebookDocumentsAndEditorsDelta } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
||||
import { CellEditType, CellUri, diff, ICellEditOperation, ICellInsertEdit, IErrorOutput, INotebookDisplayOrder, INotebookEditData, IOrderedMimeType, IStreamOutput, ITransformedDisplayOutputDto, mimeTypeSupportedByCore, NotebookCellsChangedEvent, NotebookCellsSplice2, sortMimeTypes, ICellDeleteEdit, notebookDocumentMetadataDefaults, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { CellEditType, CellUri, diff, ICellEditOperation, ICellInsertEdit, IErrorOutput, INotebookDisplayOrder, INotebookEditData, IOrderedMimeType, IStreamOutput, ITransformedDisplayOutputDto, mimeTypeSupportedByCore, NotebookCellsChangedEvent, NotebookCellsSplice2, sortMimeTypes, ICellDeleteEdit, notebookDocumentMetadataDefaults, NotebookCellsChangeType, NotebookDataDto } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { Disposable as VSCodeDisposable } from './extHostTypes';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData';
|
||||
@@ -345,8 +345,6 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||
|
||||
transformMimeTypes(output: vscode.CellDisplayOutput): ITransformedDisplayOutputDto {
|
||||
let mimeTypes = Object.keys(output.data);
|
||||
|
||||
// TODO@rebornix, the document display order might be assigned a bit later. We need to postpone sending the outputs to the core side.
|
||||
let coreDisplayOrder = this.renderingHandler.outputDisplayOrder;
|
||||
const sorted = sortMimeTypes(mimeTypes, coreDisplayOrder?.userOrder || [], this._displayOrder, coreDisplayOrder?.defaultOrder || []);
|
||||
|
||||
@@ -415,7 +413,7 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||
}
|
||||
}
|
||||
|
||||
export class NotebookEditorCellEdit {
|
||||
export class NotebookEditorCellEditBuilder implements vscode.NotebookEditorCellEdit {
|
||||
private _finalized: boolean = false;
|
||||
private readonly _documentVersionId: number;
|
||||
private _collectedEdits: ICellEditOperation[] = [];
|
||||
@@ -526,13 +524,13 @@ export class ExtHostNotebookEditor extends Disposable implements vscode.Notebook
|
||||
}));
|
||||
}
|
||||
|
||||
edit(callback: (editBuilder: NotebookEditorCellEdit) => void): Thenable<boolean> {
|
||||
const edit = new NotebookEditorCellEdit(this);
|
||||
edit(callback: (editBuilder: NotebookEditorCellEditBuilder) => void): Thenable<boolean> {
|
||||
const edit = new NotebookEditorCellEditBuilder(this);
|
||||
callback(edit);
|
||||
return this._applyEdit(edit);
|
||||
}
|
||||
|
||||
private _applyEdit(editBuilder: NotebookEditorCellEdit): Promise<boolean> {
|
||||
private _applyEdit(editBuilder: NotebookEditorCellEditBuilder): Promise<boolean> {
|
||||
const editData = editBuilder.finalize();
|
||||
|
||||
// return when there is nothing to do
|
||||
@@ -625,7 +623,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
private static _handlePool: number = 0;
|
||||
|
||||
private readonly _proxy: MainThreadNotebookShape;
|
||||
private readonly _notebookProviders = new Map<string, { readonly provider: vscode.NotebookProvider, readonly extension: IExtensionDescription; }>();
|
||||
private readonly _notebookContentProviders = new Map<string, { readonly provider: vscode.NotebookContentProvider, readonly extension: IExtensionDescription; }>();
|
||||
private readonly _documents = new Map<string, ExtHostNotebookDocument>();
|
||||
private readonly _editors = new Map<string, { editor: ExtHostNotebookEditor, onDidReceiveMessage: Emitter<any>; }>();
|
||||
@@ -706,31 +703,13 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
return matches;
|
||||
}
|
||||
|
||||
registerNotebookProvider(
|
||||
extension: IExtensionDescription,
|
||||
viewType: string,
|
||||
provider: vscode.NotebookProvider,
|
||||
): vscode.Disposable {
|
||||
|
||||
if (this._notebookProviders.has(viewType)) {
|
||||
throw new Error(`Notebook provider for '${viewType}' already registered`);
|
||||
}
|
||||
|
||||
this._notebookProviders.set(viewType, { extension, provider });
|
||||
this._proxy.$registerNotebookProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType);
|
||||
return new VSCodeDisposable(() => {
|
||||
this._notebookProviders.delete(viewType);
|
||||
this._proxy.$unregisterNotebookProvider(viewType);
|
||||
});
|
||||
}
|
||||
|
||||
registerNotebookContentProvider(
|
||||
extension: IExtensionDescription,
|
||||
viewType: string,
|
||||
provider: vscode.NotebookContentProvider,
|
||||
): vscode.Disposable {
|
||||
|
||||
if (this._notebookProviders.has(viewType)) {
|
||||
if (this._notebookContentProviders.has(viewType)) {
|
||||
throw new Error(`Notebook provider for '${viewType}' already registered`);
|
||||
}
|
||||
|
||||
@@ -742,97 +721,99 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
});
|
||||
}
|
||||
|
||||
async _resolveNotebookFromContentProvider(viewType: string, uri: UriComponents): Promise<number | undefined> {
|
||||
async $resolveNotebookData(viewType: string, uri: UriComponents): Promise<NotebookDataDto | undefined> {
|
||||
let provider = this._notebookContentProviders.get(viewType);
|
||||
let document = this._documents.get(URI.revive(uri).toString());
|
||||
|
||||
if (provider) {
|
||||
const revivedUri = URI.revive(uri);
|
||||
if (!this._documents.has(revivedUri.toString())) {
|
||||
let document = new ExtHostNotebookDocument(this._proxy, this._documentsAndEditors, viewType, revivedUri, this);
|
||||
await this._proxy.$createNotebookDocument(
|
||||
document.handle,
|
||||
viewType,
|
||||
uri
|
||||
);
|
||||
if (provider && document) {
|
||||
const rawCells = await provider.provider.openNotebook(URI.revive(uri));
|
||||
const renderers = new Set<number>();
|
||||
const dto = {
|
||||
metadata: {
|
||||
...notebookDocumentMetadataDefaults,
|
||||
...rawCells.metadata
|
||||
},
|
||||
languages: rawCells.languages,
|
||||
cells: rawCells.cells.map(cell => {
|
||||
let transformedOutputs = cell.outputs.map(output => {
|
||||
if (output.outputKind === CellOutputKind.Rich) {
|
||||
// TODO display string[]
|
||||
const ret = this._transformMimeTypes(document!, (rawCells.metadata.displayOrder as string[]) || [], output);
|
||||
|
||||
this._documents.set(revivedUri.toString(), document);
|
||||
}
|
||||
if (ret.orderedMimeTypes[ret.pickedMimeTypeIndex].isResolved) {
|
||||
renderers.add(ret.orderedMimeTypes[ret.pickedMimeTypeIndex].rendererId!);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return output as IStreamOutput | IErrorOutput;
|
||||
}
|
||||
});
|
||||
|
||||
const onDidReceiveMessage = new Emitter<any>();
|
||||
|
||||
let editor = new ExtHostNotebookEditor(
|
||||
viewType,
|
||||
`${ExtHostNotebookController._handlePool++}`,
|
||||
revivedUri,
|
||||
this._proxy,
|
||||
onDidReceiveMessage,
|
||||
this._documents.get(revivedUri.toString())!,
|
||||
this._documentsAndEditors
|
||||
);
|
||||
|
||||
this._editors.set(revivedUri.toString(), { editor, onDidReceiveMessage });
|
||||
|
||||
const data = await provider.provider.openNotebook(revivedUri);
|
||||
editor.document.languages = data.languages;
|
||||
editor.document.metadata = {
|
||||
...notebookDocumentMetadataDefaults,
|
||||
...data.metadata
|
||||
return {
|
||||
language: cell.language,
|
||||
cellKind: cell.cellKind,
|
||||
metadata: cell.metadata,
|
||||
source: cell.source,
|
||||
outputs: transformedOutputs
|
||||
};
|
||||
})
|
||||
};
|
||||
|
||||
await editor.edit(editBuilder => {
|
||||
for (let i = 0; i < data.cells.length; i++) {
|
||||
const cell = data.cells[i];
|
||||
editBuilder.insert(0, cell.source, cell.language, cell.cellKind, cell.outputs, cell.metadata);
|
||||
}
|
||||
});
|
||||
|
||||
this._onDidOpenNotebookDocument.fire(editor.document);
|
||||
return editor.document.handle;
|
||||
} else {
|
||||
return Promise.resolve(undefined);
|
||||
return dto;
|
||||
}
|
||||
|
||||
return undefined; // {{SQL CARBON EDIT}}
|
||||
}
|
||||
|
||||
async $resolveNotebook(viewType: string, uri: UriComponents): Promise<number | undefined> {
|
||||
let notebookFromNotebookContentProvider = await this._resolveNotebookFromContentProvider(viewType, uri);
|
||||
private _transformMimeTypes(document: ExtHostNotebookDocument, displayOrder: string[], output: vscode.CellDisplayOutput): ITransformedDisplayOutputDto {
|
||||
let mimeTypes = Object.keys(output.data);
|
||||
let coreDisplayOrder = this.outputDisplayOrder;
|
||||
const sorted = sortMimeTypes(mimeTypes, coreDisplayOrder?.userOrder || [], displayOrder, coreDisplayOrder?.defaultOrder || []);
|
||||
|
||||
if (notebookFromNotebookContentProvider !== undefined) {
|
||||
return notebookFromNotebookContentProvider;
|
||||
}
|
||||
let orderMimeTypes: IOrderedMimeType[] = [];
|
||||
|
||||
let provider = this._notebookProviders.get(viewType);
|
||||
sorted.forEach(mimeType => {
|
||||
let handlers = this.findBestMatchedRenderer(mimeType);
|
||||
|
||||
if (provider) {
|
||||
if (!this._documents.has(URI.revive(uri).toString())) {
|
||||
let document = new ExtHostNotebookDocument(this._proxy, this._documentsAndEditors, viewType, URI.revive(uri), this);
|
||||
await this._proxy.$createNotebookDocument(
|
||||
document.handle,
|
||||
viewType,
|
||||
uri
|
||||
);
|
||||
if (handlers.length) {
|
||||
let renderedOutput = handlers[0].render(document, output, mimeType);
|
||||
|
||||
this._documents.set(URI.revive(uri).toString(), document);
|
||||
orderMimeTypes.push({
|
||||
mimeType: mimeType,
|
||||
isResolved: true,
|
||||
rendererId: handlers[0].handle,
|
||||
output: renderedOutput
|
||||
});
|
||||
|
||||
for (let i = 1; i < handlers.length; i++) {
|
||||
orderMimeTypes.push({
|
||||
mimeType: mimeType,
|
||||
isResolved: false,
|
||||
rendererId: handlers[i].handle
|
||||
});
|
||||
}
|
||||
|
||||
if (mimeTypeSupportedByCore(mimeType)) {
|
||||
orderMimeTypes.push({
|
||||
mimeType: mimeType,
|
||||
isResolved: false,
|
||||
rendererId: -1
|
||||
});
|
||||
}
|
||||
} else {
|
||||
orderMimeTypes.push({
|
||||
mimeType: mimeType,
|
||||
isResolved: false
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const onDidReceiveMessage = new Emitter<any>();
|
||||
|
||||
let editor = new ExtHostNotebookEditor(
|
||||
viewType,
|
||||
`${ExtHostNotebookController._handlePool++}`,
|
||||
URI.revive(uri),
|
||||
this._proxy,
|
||||
onDidReceiveMessage,
|
||||
this._documents.get(URI.revive(uri).toString())!,
|
||||
this._documentsAndEditors
|
||||
);
|
||||
|
||||
this._editors.set(URI.revive(uri).toString(), { editor, onDidReceiveMessage });
|
||||
await provider.provider.resolveNotebook(editor);
|
||||
// await editor.document.$updateCells();
|
||||
return editor.document.handle;
|
||||
}
|
||||
|
||||
return Promise.resolve(undefined);
|
||||
return {
|
||||
outputKind: output.outputKind,
|
||||
data: output.data,
|
||||
orderedMimeTypes: orderMimeTypes,
|
||||
pickedMimeTypeIndex: 0
|
||||
};
|
||||
}
|
||||
|
||||
async $executeNotebook(viewType: string, uri: UriComponents, cellHandle: number | undefined, token: CancellationToken): Promise<void> {
|
||||
@@ -847,15 +828,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
|
||||
return this._notebookContentProviders.get(viewType)!.provider.executeCell(document, cell, token);
|
||||
}
|
||||
|
||||
let provider = this._notebookProviders.get(viewType);
|
||||
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
let cell = cellHandle !== undefined ? document.getCell(cellHandle) : undefined;
|
||||
return provider.provider.executeCell(document!, cell, token);
|
||||
}
|
||||
|
||||
async $saveNotebook(viewType: string, uri: UriComponents, token: CancellationToken): Promise<boolean> {
|
||||
@@ -874,44 +846,26 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
return true;
|
||||
}
|
||||
|
||||
let provider = this._notebookProviders.get(viewType);
|
||||
|
||||
if (provider && document) {
|
||||
return await provider.provider.save(document);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async $updateActiveEditor(viewType: string, uri: UriComponents): Promise<void> {
|
||||
this._activeNotebookDocument = this._documents.get(URI.revive(uri).toString());
|
||||
this._activeNotebookEditor = this._editors.get(URI.revive(uri).toString())?.editor;
|
||||
}
|
||||
|
||||
async $destoryNotebookDocument(viewType: string, uri: UriComponents): Promise<boolean> {
|
||||
let provider = this._notebookProviders.get(viewType);
|
||||
|
||||
if (!provider) {
|
||||
async $saveNotebookAs(viewType: string, uri: UriComponents, target: UriComponents, token: CancellationToken): Promise<boolean> {
|
||||
let document = this._documents.get(URI.revive(uri).toString());
|
||||
if (!document) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let document = this._documents.get(URI.revive(uri).toString());
|
||||
if (this._notebookContentProviders.has(viewType)) {
|
||||
try {
|
||||
await this._notebookContentProviders.get(viewType)!.provider.saveNotebookAs(URI.revive(target), document, token);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (document) {
|
||||
document.dispose();
|
||||
this._documents.delete(URI.revive(uri).toString());
|
||||
this._onDidCloseNotebookDocument.fire(document);
|
||||
return true;
|
||||
}
|
||||
|
||||
let editor = this._editors.get(URI.revive(uri).toString());
|
||||
|
||||
if (editor) {
|
||||
editor.editor.dispose();
|
||||
editor.onDidReceiveMessage.dispose();
|
||||
this._editors.delete(URI.revive(uri).toString());
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
$acceptDisplayOrder(displayOrder: INotebookDisplayOrder): void {
|
||||
@@ -957,4 +911,60 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async $acceptDocumentAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta) {
|
||||
if (delta.removedDocuments) {
|
||||
delta.removedDocuments.forEach((uri) => {
|
||||
let document = this._documents.get(URI.revive(uri).toString());
|
||||
|
||||
if (document) {
|
||||
document.dispose();
|
||||
this._documents.delete(URI.revive(uri).toString());
|
||||
this._onDidCloseNotebookDocument.fire(document);
|
||||
}
|
||||
|
||||
let editor = this._editors.get(URI.revive(uri).toString());
|
||||
|
||||
if (editor) {
|
||||
editor.editor.dispose();
|
||||
editor.onDidReceiveMessage.dispose();
|
||||
this._editors.delete(URI.revive(uri).toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (delta.addedDocuments) {
|
||||
delta.addedDocuments.forEach(modelData => {
|
||||
const revivedUri = URI.revive(modelData.uri);
|
||||
const viewType = modelData.viewType;
|
||||
if (!this._documents.has(revivedUri.toString())) {
|
||||
let document = new ExtHostNotebookDocument(this._proxy, this._documentsAndEditors, viewType, revivedUri, this);
|
||||
this._documents.set(revivedUri.toString(), document);
|
||||
}
|
||||
|
||||
const onDidReceiveMessage = new Emitter<any>();
|
||||
const document = this._documents.get(revivedUri.toString())!;
|
||||
|
||||
let editor = new ExtHostNotebookEditor(
|
||||
viewType,
|
||||
`${ExtHostNotebookController._handlePool++}`,
|
||||
revivedUri,
|
||||
this._proxy,
|
||||
onDidReceiveMessage,
|
||||
document,
|
||||
this._documentsAndEditors
|
||||
);
|
||||
|
||||
this._onDidOpenNotebookDocument.fire(document);
|
||||
|
||||
// TODO, does it already exist?
|
||||
this._editors.set(revivedUri.toString(), { editor, onDidReceiveMessage });
|
||||
});
|
||||
}
|
||||
|
||||
if (delta.newActiveEditor) {
|
||||
this._activeNotebookDocument = this._documents.get(URI.revive(delta.newActiveEditor).toString());
|
||||
this._activeNotebookEditor = this._editors.get(URI.revive(delta.newActiveEditor).toString())?.editor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2742,3 +2742,27 @@ export class TimelineItem implements vscode.TimelineItem {
|
||||
}
|
||||
|
||||
//#endregion Timeline
|
||||
|
||||
//#region ExtensionContext
|
||||
|
||||
export enum ExtensionMode {
|
||||
/**
|
||||
* The extension is installed normally (for example, from the marketplace
|
||||
* or VSIX) in VS Code.
|
||||
*/
|
||||
Release = 1,
|
||||
|
||||
/**
|
||||
* The extension is running from an `--extensionDevelopmentPath` provided
|
||||
* when launching VS Code.
|
||||
*/
|
||||
Development = 2,
|
||||
|
||||
/**
|
||||
* The extension is running from an `--extensionDevelopmentPath` and
|
||||
* the extension host is running unit tests.
|
||||
*/
|
||||
Test = 3,
|
||||
}
|
||||
|
||||
//#endregion ExtensionContext
|
||||
|
||||
@@ -37,7 +37,6 @@ namespace schema {
|
||||
case 'debug/callstack/context': return MenuId.DebugCallStackContext;
|
||||
case 'debug/toolbar': return MenuId.DebugToolBar;
|
||||
case 'debug/toolBar': return MenuId.DebugToolBar;
|
||||
case 'menuBar/file': return MenuId.MenubarFileMenu;
|
||||
case 'menuBar/webNavigation': return MenuId.MenubarWebNavigationMenu;
|
||||
case 'scm/title': return MenuId.SCMTitle;
|
||||
case 'scm/sourceControl': return MenuId.SCMSourceControl;
|
||||
@@ -70,7 +69,6 @@ namespace schema {
|
||||
export function isProposedAPI(menuId: MenuId): boolean {
|
||||
switch (menuId) {
|
||||
case MenuId.StatusBarWindowIndicatorMenu:
|
||||
case MenuId.MenubarFileMenu:
|
||||
case MenuId.MenubarWebNavigationMenu:
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -230,13 +230,10 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService {
|
||||
|
||||
public getEnvironmentVariableCollection(extension: IExtensionDescription): vscode.EnvironmentVariableCollection {
|
||||
let collection = this._environmentVariableCollections.get(extension.identifier.value);
|
||||
|
||||
if (!collection) {
|
||||
// TODO: Disable dispose
|
||||
collection = new EnvironmentVariableCollection();
|
||||
this._setEnvironmentVariableCollection(extension.identifier.value, collection);
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user