mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-13 03:28:33 -05:00
Merge from vscode 79a1f5a5ca0c6c53db617aa1fa5a2396d2caebe2
This commit is contained in:
@@ -8,11 +8,12 @@ import * as objects from 'vs/base/common/objects';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import { ExtensionsRegistry, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { IConfigurationNode, IConfigurationRegistry, Extensions, resourceLanguageSettingsSchemaId, IDefaultConfigurationExtension, validateProperty, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IConfigurationNode, IConfigurationRegistry, Extensions, resourceLanguageSettingsSchemaId, IDefaultConfigurationExtension, validateProperty, ConfigurationScope, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IJSONContributionRegistry, Extensions as JSONExtensions } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
|
||||
import { workspaceSettingsSchemaId, launchSchemaId, tasksSchemaId } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { isObject } from 'vs/base/common/types';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
|
||||
const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
|
||||
|
||||
@@ -116,7 +117,13 @@ defaultConfigurationExtPoint.setHandler((extensions, { added, removed }) => {
|
||||
const addedDefaultConfigurations = added.map(extension => {
|
||||
const id = extension.description.identifier;
|
||||
const name = extension.description.name;
|
||||
const defaults = objects.deepClone(extension.value);
|
||||
const defaults: IStringDictionary<any> = objects.deepClone(extension.value);
|
||||
for (const key of Object.keys(defaults)) {
|
||||
if (!OVERRIDE_PROPERTY_PATTERN.test(key) || typeof defaults[key] !== 'object') {
|
||||
extension.collector.warn(nls.localize('config.property.defaultConfiguration.warning', "Cannot register configuration defaults for '{0}'. Only defaults for language specific settings are supported.", key));
|
||||
delete defaults[key];
|
||||
}
|
||||
}
|
||||
return <IDefaultConfigurationExtension>{
|
||||
id, name, defaults
|
||||
};
|
||||
|
||||
@@ -135,7 +135,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol));
|
||||
const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress)));
|
||||
const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol));
|
||||
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors));
|
||||
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors, initData.environment));
|
||||
const extHostTheming = rpcProtocol.set(ExtHostContext.ExtHostTheming, new ExtHostTheming(rpcProtocol));
|
||||
const extHostAuthentication = rpcProtocol.set(ExtHostContext.ExtHostAuthentication, new ExtHostAuthentication(rpcProtocol));
|
||||
const extHostTimeline = rpcProtocol.set(ExtHostContext.ExtHostTimeline, new ExtHostTimeline(rpcProtocol, extHostCommands));
|
||||
@@ -196,9 +196,18 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
get onDidChangeAuthenticationProviders(): Event<vscode.AuthenticationProvidersChangeEvent> {
|
||||
return extHostAuthentication.onDidChangeAuthenticationProviders;
|
||||
},
|
||||
getProviderIds(): Thenable<ReadonlyArray<string>> {
|
||||
return extHostAuthentication.getProviderIds();
|
||||
},
|
||||
get providerIds(): string[] {
|
||||
return extHostAuthentication.providerIds;
|
||||
},
|
||||
hasSessions(providerId: string, scopes: string[]): Thenable<boolean> {
|
||||
return extHostAuthentication.hasSessions(providerId, scopes);
|
||||
},
|
||||
getSession(providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions) {
|
||||
return extHostAuthentication.getSession(extension, providerId, scopes, options as any);
|
||||
},
|
||||
getSessions(providerId: string, scopes: string[]): Thenable<readonly vscode.AuthenticationSession[]> {
|
||||
return extHostAuthentication.getSessions(extension, providerId, scopes);
|
||||
},
|
||||
@@ -265,7 +274,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
get sessionId() { return initData.telemetryInfo.sessionId; },
|
||||
get language() { return initData.environment.appLanguage; },
|
||||
get appName() { return initData.environment.appName; },
|
||||
get appRoot() { return initData.environment.appRoot!.fsPath; },
|
||||
get appRoot() { return initData.environment.appRoot?.fsPath ?? '<UNKNOWN_APP_ROOT>'; },
|
||||
get uriScheme() { return initData.environment.appUriScheme; },
|
||||
get logLevel() {
|
||||
checkProposedApiEnabled(extension);
|
||||
@@ -428,6 +437,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
},
|
||||
setLanguageConfiguration: (language: string, configuration: vscode.LanguageConfiguration): vscode.Disposable => {
|
||||
return extHostLanguageFeatures.setLanguageConfiguration(extension, language, configuration);
|
||||
},
|
||||
getTokenInformationAtPosition(doc: vscode.TextDocument, pos: vscode.Position) {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostLanguages.tokenAtPosition(doc, pos);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -528,12 +541,14 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
let id: string;
|
||||
let name: string;
|
||||
let alignment: number | undefined;
|
||||
let accessibilityInformation: vscode.AccessibilityInformation | undefined = undefined;
|
||||
|
||||
if (alignmentOrOptions && typeof alignmentOrOptions !== 'number') {
|
||||
id = alignmentOrOptions.id;
|
||||
name = alignmentOrOptions.name;
|
||||
alignment = alignmentOrOptions.alignment;
|
||||
priority = alignmentOrOptions.priority;
|
||||
accessibilityInformation = alignmentOrOptions.accessibilityInformation;
|
||||
} else {
|
||||
id = extension.identifier.value;
|
||||
name = nls.localize('extensionLabel', "{0} (Extension)", extension.displayName || extension.name);
|
||||
@@ -541,7 +556,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
priority = priority;
|
||||
}
|
||||
|
||||
return extHostStatusBar.createStatusBarEntry(id, name, alignment, priority);
|
||||
return extHostStatusBar.createStatusBarEntry(id, name, alignment, priority, accessibilityInformation);
|
||||
},
|
||||
setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): vscode.Disposable {
|
||||
return extHostStatusBar.setStatusBarMessage(text, timeoutOrThenable);
|
||||
@@ -703,8 +718,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
}
|
||||
|
||||
return uriPromise.then(uri => {
|
||||
return extHostDocuments.ensureDocumentData(uri).then(() => {
|
||||
return extHostDocuments.getDocument(uri);
|
||||
return extHostDocuments.ensureDocumentData(uri).then(documentData => {
|
||||
return documentData.document;
|
||||
});
|
||||
});
|
||||
},
|
||||
@@ -931,10 +946,20 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.onDidCloseNotebookDocument;
|
||||
},
|
||||
get visibleNotebookEditors() {
|
||||
return extHostNotebook.visibleNotebookEditors;
|
||||
},
|
||||
get onDidChangeVisibleNotebookEditors() {
|
||||
return extHostNotebook.onDidChangeVisibleNotebookEditors;
|
||||
},
|
||||
registerNotebookContentProvider: (viewType: string, provider: vscode.NotebookContentProvider) => {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.registerNotebookContentProvider(extension, viewType, provider);
|
||||
},
|
||||
registerNotebookKernel: (id: string, selector: vscode.GlobPattern[], kernel: vscode.NotebookKernel) => {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.registerNotebookKernel(extension, id, selector, kernel);
|
||||
},
|
||||
registerNotebookOutputRenderer: (type: string, outputFilter: vscode.NotebookOutputSelector, renderer: vscode.NotebookOutputRenderer) => {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.registerNotebookOutputRenderer(type, extension, outputFilter, renderer);
|
||||
@@ -947,9 +972,21 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.activeNotebookEditor;
|
||||
},
|
||||
onDidChangeNotebookDocument(listener, thisArgs?, disposables?) {
|
||||
onDidChangeActiveNotebookEditor(listener, thisArgs?, disposables?) {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.onDidChangeNotebookDocument(listener, thisArgs, disposables);
|
||||
return extHostNotebook.onDidChangeActiveNotebookEditor(listener, thisArgs, disposables);
|
||||
},
|
||||
onDidChangeNotebookCells(listener, thisArgs?, disposables?) {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.onDidChangeNotebookCells(listener, thisArgs, disposables);
|
||||
},
|
||||
onDidChangeCellOutputs(listener, thisArgs?, disposables?) {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.onDidChangeCellOutputs(listener, thisArgs, disposables);
|
||||
},
|
||||
onDidChangeCellLanguage(listener, thisArgs?, disposables?) {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostNotebook.onDidChangeCellLanguage(listener, thisArgs, disposables);
|
||||
},
|
||||
createConcatTextDocument(notebook, selector) {
|
||||
checkProposedApiEnabled(extension);
|
||||
@@ -1050,6 +1087,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
SnippetString: extHostTypes.SnippetString,
|
||||
SourceBreakpoint: extHostTypes.SourceBreakpoint,
|
||||
SourceControlInputBoxValidationType: extHostTypes.SourceControlInputBoxValidationType,
|
||||
StandardTokenType: extHostTypes.StandardTokenType,
|
||||
StatusBarAlignment: extHostTypes.StatusBarAlignment,
|
||||
SymbolInformation: extHostTypes.SymbolInformation,
|
||||
SymbolKind: extHostTypes.SymbolKind,
|
||||
@@ -1086,7 +1124,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
TimelineItem: extHostTypes.TimelineItem,
|
||||
CellKind: extHostTypes.CellKind,
|
||||
CellOutputKind: extHostTypes.CellOutputKind,
|
||||
NotebookCellRunState: extHostTypes.NotebookCellRunState
|
||||
NotebookCellRunState: extHostTypes.NotebookCellRunState,
|
||||
AuthenticationSession2: extHostTypes.AuthenticationSession
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,11 +51,12 @@ 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, NotebookDataDto } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookMimeTypeSelector, IProcessedOutput, INotebookDisplayOrder, NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEvent, NotebookDataDto, INotebookKernelInfoDto, IMainCellDto, IOutputRenderRequest, IOutputRenderResponse, IRawOutput } 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';
|
||||
import { DebugConfigurationProviderTriggerKind } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { IAccessibilityInformation } from 'vs/platform/accessibility/common/accessibility';
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
import { ITreeItem as sqlITreeItem } from 'sql/workbench/common/views';
|
||||
@@ -161,12 +162,20 @@ export interface MainThreadCommentsShape extends IDisposable {
|
||||
}
|
||||
|
||||
export interface MainThreadAuthenticationShape extends IDisposable {
|
||||
$registerAuthenticationProvider(id: string, displayName: string): void;
|
||||
$registerAuthenticationProvider(id: string, displayName: string, supportsMultipleAccounts: boolean): void;
|
||||
$unregisterAuthenticationProvider(id: string): void;
|
||||
$onDidChangeSessions(providerId: string, event: modes.AuthenticationSessionsChangeEvent): void;
|
||||
$getProviderIds(): Promise<string[]>;
|
||||
$sendDidChangeSessions(providerId: string, event: modes.AuthenticationSessionsChangeEvent): void;
|
||||
$getSession(providerId: string, scopes: string[], extensionId: string, extensionName: string, options: { createIfNone?: boolean, clearSessionPreference?: boolean }): Promise<modes.AuthenticationSession | undefined>;
|
||||
$selectSession(providerId: string, providerName: string, extensionId: string, extensionName: string, potentialSessions: modes.AuthenticationSession[], scopes: string[], clearSessionPreference: boolean): Promise<modes.AuthenticationSession>;
|
||||
$getSessionsPrompt(providerId: string, accountName: string, providerName: string, extensionId: string, extensionName: string): Promise<boolean>;
|
||||
$loginPrompt(providerName: string, extensionName: string): Promise<boolean>;
|
||||
$setTrustedExtension(providerId: string, accountName: string, extensionId: string, extensionName: string): Promise<void>;
|
||||
$requestNewSession(providerId: string, scopes: string[], extensionId: string, extensionName: string): Promise<void>;
|
||||
|
||||
$getSessions(providerId: string): Promise<ReadonlyArray<modes.AuthenticationSession>>;
|
||||
$login(providerId: string, scopes: string[]): Promise<modes.AuthenticationSession>;
|
||||
$logout(providerId: string, sessionId: string): Promise<void>;
|
||||
}
|
||||
|
||||
export interface MainThreadConfigurationShape extends IDisposable {
|
||||
@@ -215,7 +224,7 @@ export interface MainThreadDocumentContentProvidersShape extends IDisposable {
|
||||
|
||||
export interface MainThreadDocumentsShape extends IDisposable {
|
||||
$tryCreateDocument(options?: { language?: string; content?: string; }): Promise<UriComponents>;
|
||||
$tryOpenDocument(uri: UriComponents): Promise<void>;
|
||||
$tryOpenDocument(uri: UriComponents): Promise<UriComponents>;
|
||||
$trySaveDocument(uri: UriComponents): Promise<boolean>;
|
||||
}
|
||||
|
||||
@@ -394,6 +403,7 @@ export interface MainThreadLanguageFeaturesShape extends IDisposable {
|
||||
export interface MainThreadLanguagesShape extends IDisposable {
|
||||
$getLanguages(): Promise<string[]>;
|
||||
$changeLanguage(resource: UriComponents, languageId: string): Promise<void>;
|
||||
$tokensAtPosition(resource: UriComponents, position: IPosition): Promise<undefined | { type: modes.StandardTokenType, range: IRange }>;
|
||||
}
|
||||
|
||||
export interface MainThreadMessageOptions {
|
||||
@@ -547,7 +557,7 @@ export interface MainThreadQuickOpenShape extends IDisposable {
|
||||
}
|
||||
|
||||
export interface MainThreadStatusBarShape extends IDisposable {
|
||||
$setEntry(id: number, statusId: string, statusName: string, text: string, tooltip: string | undefined, command: ICommandDto | undefined, color: string | ThemeColor | undefined, alignment: statusbar.StatusbarAlignment, priority: number | undefined): void;
|
||||
$setEntry(id: number, statusId: string, statusName: string, text: string, tooltip: string | undefined, command: ICommandDto | undefined, color: string | ThemeColor | undefined, alignment: statusbar.StatusbarAlignment, priority: number | undefined, accessibilityInformation: IAccessibilityInformation | undefined): void;
|
||||
$dispose(id: number): void;
|
||||
}
|
||||
|
||||
@@ -674,7 +684,7 @@ export interface ICellDto {
|
||||
source: string[];
|
||||
language: string;
|
||||
cellKind: CellKind;
|
||||
outputs: IOutput[];
|
||||
outputs: IProcessedOutput[];
|
||||
metadata?: NotebookCellMetadata;
|
||||
}
|
||||
|
||||
@@ -687,14 +697,17 @@ export type NotebookCellsSplice = [
|
||||
export type NotebookCellOutputsSplice = [
|
||||
number /* start */,
|
||||
number /* delete count */,
|
||||
IOutput[]
|
||||
IRawOutput[]
|
||||
];
|
||||
|
||||
export interface MainThreadNotebookShape extends IDisposable {
|
||||
$registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string): Promise<void>;
|
||||
$registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string, kernelInfoDto: INotebookKernelInfoDto | undefined): Promise<void>;
|
||||
$onNotebookChange(viewType: string, resource: UriComponents): Promise<void>;
|
||||
$unregisterNotebookProvider(viewType: string): Promise<void>;
|
||||
$registerNotebookRenderer(extension: NotebookExtensionDescription, type: string, selectors: INotebookMimeTypeSelector, handle: number, preloads: UriComponents[]): Promise<void>;
|
||||
$unregisterNotebookRenderer(handle: number): Promise<void>;
|
||||
$registerNotebookRenderer(extension: NotebookExtensionDescription, type: string, selectors: INotebookMimeTypeSelector, preloads: UriComponents[]): Promise<void>;
|
||||
$unregisterNotebookRenderer(id: string): Promise<void>;
|
||||
$registerNotebookKernel(extension: NotebookExtensionDescription, id: string, label: string, selectors: (string | IRelativePattern)[], preloads: UriComponents[]): Promise<void>;
|
||||
$unregisterNotebookKernel(id: string): 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>;
|
||||
@@ -1006,6 +1019,8 @@ export interface ExtHostAuthenticationShape {
|
||||
$getSessionAccessToken(id: string, sessionId: string): Promise<string>;
|
||||
$login(id: string, scopes: string[]): Promise<modes.AuthenticationSession>;
|
||||
$logout(id: string, sessionId: string): Promise<void>;
|
||||
$onDidChangeAuthenticationSessions(providerId: string, event: modes.AuthenticationSessionsChangeEvent): Promise<void>;
|
||||
$onDidChangeAuthenticationProviders(added: string[], removed: string[]): Promise<void>;
|
||||
}
|
||||
|
||||
export interface ExtHostSearchShape {
|
||||
@@ -1539,30 +1554,44 @@ export interface INotebookSelectionChangeEvent {
|
||||
|
||||
export interface INotebookEditorPropertiesChangeData {
|
||||
selections: INotebookSelectionChangeEvent | null;
|
||||
metadata: NotebookDocumentMetadata | null;
|
||||
}
|
||||
|
||||
export interface INotebookModelAddedData {
|
||||
uri: UriComponents;
|
||||
handle: number;
|
||||
// versionId: number;
|
||||
versionId: number;
|
||||
cells: IMainCellDto[],
|
||||
viewType: string;
|
||||
metadata?: NotebookDocumentMetadata;
|
||||
attachedEditor?: { id: string; selections: number[]; }
|
||||
}
|
||||
|
||||
export interface INotebookEditorAddData {
|
||||
id: string;
|
||||
documentUri: UriComponents;
|
||||
selections: number[];
|
||||
}
|
||||
|
||||
export interface INotebookDocumentsAndEditorsDelta {
|
||||
removedDocuments?: UriComponents[];
|
||||
addedDocuments?: INotebookModelAddedData[];
|
||||
// removedEditors?: string[];
|
||||
// addedEditors?: ITextEditorAddData[];
|
||||
newActiveEditor?: UriComponents | null;
|
||||
removedEditors?: string[];
|
||||
addedEditors?: INotebookEditorAddData[];
|
||||
newActiveEditor?: string | null;
|
||||
visibleEditors?: string[];
|
||||
}
|
||||
|
||||
export interface ExtHostNotebookShape {
|
||||
$resolveNotebookData(viewType: string, uri: UriComponents): Promise<NotebookDataDto | undefined>;
|
||||
$executeNotebook(viewType: string, uri: UriComponents, cellHandle: number | undefined, token: CancellationToken): Promise<void>;
|
||||
$executeNotebook(viewType: string, uri: UriComponents, cellHandle: number | undefined, useAttachedKernel: boolean, token: CancellationToken): Promise<void>;
|
||||
$executeNotebook2(kernelId: string, viewType: string, uri: UriComponents, cellHandle: number | undefined, token: CancellationToken): Promise<void>;
|
||||
$saveNotebook(viewType: string, uri: UriComponents, token: CancellationToken): Promise<boolean>;
|
||||
$saveNotebookAs(viewType: string, uri: UriComponents, target: UriComponents, token: CancellationToken): Promise<boolean>;
|
||||
$acceptDisplayOrder(displayOrder: INotebookDisplayOrder): void;
|
||||
$onDidReceiveMessage(uri: UriComponents, message: any): void;
|
||||
$renderOutputs(uriComponents: UriComponents, id: string, request: IOutputRenderRequest<UriComponents>): Promise<IOutputRenderResponse<UriComponents> | undefined>;
|
||||
$renderOutputs2<T>(uriComponents: UriComponents, id: string, request: IOutputRenderRequest<T>): Promise<IOutputRenderResponse<T> | undefined>;
|
||||
$onDidReceiveMessage(editorId: string, message: any): void;
|
||||
$acceptModelChanged(uriComponents: UriComponents, event: NotebookCellsChangedEvent): void;
|
||||
$acceptEditorPropertiesChanged(uriComponents: UriComponents, data: INotebookEditorPropertiesChangeData): void;
|
||||
$acceptDocumentAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta): Promise<void>;
|
||||
|
||||
@@ -24,6 +24,10 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadAuthentication);
|
||||
}
|
||||
|
||||
getProviderIds(): Promise<ReadonlyArray<string>> {
|
||||
return this._proxy.$getProviderIds();
|
||||
}
|
||||
|
||||
get providerIds(): string[] {
|
||||
const ids: string[] = [];
|
||||
this._authenticationProviders.forEach(provider => {
|
||||
@@ -33,16 +37,74 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
return ids;
|
||||
}
|
||||
|
||||
async getSessions(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise<readonly vscode.AuthenticationSession[]> {
|
||||
private async resolveSessions(providerId: string): Promise<ReadonlyArray<modes.AuthenticationSession>> {
|
||||
const provider = this._authenticationProviders.get(providerId);
|
||||
|
||||
let sessions;
|
||||
if (!provider) {
|
||||
throw new Error(`No authentication provider with id '${providerId}' is currently registered.`);
|
||||
sessions = await this._proxy.$getSessions(providerId);
|
||||
} else {
|
||||
sessions = await provider.getSessions();
|
||||
}
|
||||
|
||||
return sessions;
|
||||
}
|
||||
|
||||
async hasSessions(providerId: string, scopes: string[]): Promise<boolean> {
|
||||
const orderedScopes = scopes.sort().join(' ');
|
||||
const sessions = await this.resolveSessions(providerId);
|
||||
return !!(sessions.filter(session => session.scopes.sort().join(' ') === orderedScopes).length);
|
||||
}
|
||||
|
||||
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions & { createIfNone: true }): Promise<vscode.AuthenticationSession2>;
|
||||
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions): Promise<vscode.AuthenticationSession2 | undefined> {
|
||||
const provider = this._authenticationProviders.get(providerId);
|
||||
const extensionName = requestingExtension.displayName || requestingExtension.name;
|
||||
const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier);
|
||||
|
||||
if (!provider) {
|
||||
return this._proxy.$getSession(providerId, scopes, extensionId, extensionName, options);
|
||||
}
|
||||
|
||||
const orderedScopes = scopes.sort().join(' ');
|
||||
const sessions = (await provider.getSessions()).filter(session => session.scopes.sort().join(' ') === orderedScopes);
|
||||
|
||||
if (sessions.length) {
|
||||
if (!provider.supportsMultipleAccounts) {
|
||||
const session = sessions[0];
|
||||
const allowed = await this._proxy.$getSessionsPrompt(providerId, session.account.displayName, provider.displayName, extensionId, extensionName);
|
||||
if (allowed) {
|
||||
return session;
|
||||
} else {
|
||||
throw new Error('User did not consent to login.');
|
||||
}
|
||||
}
|
||||
|
||||
// On renderer side, confirm consent, ask user to choose between accounts if multiple sessions are valid
|
||||
const selected = await this._proxy.$selectSession(providerId, provider.displayName, extensionId, extensionName, sessions, scopes, !!options.clearSessionPreference);
|
||||
return sessions.find(session => session.id === selected.id);
|
||||
} else {
|
||||
if (options.createIfNone) {
|
||||
const isAllowed = await this._proxy.$loginPrompt(provider.displayName, extensionName);
|
||||
if (!isAllowed) {
|
||||
throw new Error('User did not consent to login.');
|
||||
}
|
||||
|
||||
const session = await provider.login(scopes);
|
||||
await this._proxy.$setTrustedExtension(providerId, session.account.displayName, extensionId, extensionName);
|
||||
return session;
|
||||
} else {
|
||||
await this._proxy.$requestNewSession(providerId, scopes, extensionId, extensionName);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async getSessions(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise<readonly vscode.AuthenticationSession[]> {
|
||||
const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier);
|
||||
const orderedScopes = scopes.sort().join(' ');
|
||||
|
||||
return (await provider.getSessions())
|
||||
const sessions = await this.resolveSessions(providerId);
|
||||
return sessions
|
||||
.filter(session => session.scopes.sort().join(' ') === orderedScopes)
|
||||
.map(session => {
|
||||
return {
|
||||
@@ -51,9 +113,10 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
scopes: session.scopes,
|
||||
getAccessToken: async () => {
|
||||
const isAllowed = await this._proxy.$getSessionsPrompt(
|
||||
provider.id,
|
||||
providerId,
|
||||
session.account.displayName,
|
||||
provider.displayName,
|
||||
'', // TODO
|
||||
// provider.displayName,
|
||||
extensionId,
|
||||
requestingExtension.displayName || requestingExtension.name);
|
||||
|
||||
@@ -61,7 +124,7 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
throw new Error('User did not consent to token access.');
|
||||
}
|
||||
|
||||
return session.getAccessToken();
|
||||
return session.accessToken;
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -97,7 +160,7 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
throw new Error('User did not consent to token access.');
|
||||
}
|
||||
|
||||
return session.getAccessToken();
|
||||
return session.accessToken;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -105,7 +168,7 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
async logout(providerId: string, sessionId: string): Promise<void> {
|
||||
const provider = this._authenticationProviders.get(providerId);
|
||||
if (!provider) {
|
||||
throw new Error(`No authentication provider with id '${providerId}' is currently registered.`);
|
||||
return this._proxy.$logout(providerId, sessionId);
|
||||
}
|
||||
|
||||
return provider.logout(sessionId);
|
||||
@@ -119,18 +182,15 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
this._authenticationProviders.set(provider.id, provider);
|
||||
|
||||
const listener = provider.onDidChangeSessions(e => {
|
||||
this._proxy.$onDidChangeSessions(provider.id, e);
|
||||
this._onDidChangeSessions.fire({ [provider.id]: e });
|
||||
this._proxy.$sendDidChangeSessions(provider.id, e);
|
||||
});
|
||||
|
||||
this._proxy.$registerAuthenticationProvider(provider.id, provider.displayName);
|
||||
this._onDidChangeAuthenticationProviders.fire({ added: [provider.id], removed: [] });
|
||||
this._proxy.$registerAuthenticationProvider(provider.id, provider.displayName, provider.supportsMultipleAccounts);
|
||||
|
||||
return new Disposable(() => {
|
||||
listener.dispose();
|
||||
this._authenticationProviders.delete(provider.id);
|
||||
this._proxy.$unregisterAuthenticationProvider(provider.id);
|
||||
this._onDidChangeAuthenticationProviders.fire({ added: [], removed: [provider.id] });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -167,7 +227,7 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
const sessions = await authProvider.getSessions();
|
||||
const session = sessions.find(session => session.id === sessionId);
|
||||
if (session) {
|
||||
return session.getAccessToken();
|
||||
return session.accessToken;
|
||||
}
|
||||
|
||||
throw new Error(`Unable to find session with id: ${sessionId}`);
|
||||
@@ -175,4 +235,14 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
|
||||
throw new Error(`Unable to find authentication provider with handle: ${providerId}`);
|
||||
}
|
||||
|
||||
$onDidChangeAuthenticationSessions(providerId: string, event: modes.AuthenticationSessionsChangeEvent) {
|
||||
this._onDidChangeSessions.fire({ [providerId]: event });
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
$onDidChangeAuthenticationProviders(added: string[], removed: string[]) {
|
||||
this._onDidChangeAuthenticationProviders.fire({ added, removed });
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,10 @@ import { MainContext, ExtHostDecorationsShape, MainThreadDecorationsShape, Decor
|
||||
import { Disposable, Decoration } from 'vs/workbench/api/common/extHostTypes';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { asArray } from 'vs/base/common/arrays';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { asArray } from 'vs/base/common/arrays';
|
||||
|
||||
interface ProviderData {
|
||||
provider: vscode.DecorationProvider;
|
||||
@@ -40,7 +40,9 @@ export class ExtHostDecorations implements IExtHostDecorations {
|
||||
this._proxy.$registerDecorationProvider(handle, extensionId.value);
|
||||
|
||||
const listener = provider.onDidChangeDecorations(e => {
|
||||
this._proxy.$onDidChange(handle, !e ? null : asArray(e));
|
||||
this._proxy.$onDidChange(handle, !e || (Array.isArray(e) && e.length > 250)
|
||||
? null
|
||||
: asArray(e));
|
||||
});
|
||||
|
||||
return new Disposable(() => {
|
||||
|
||||
@@ -84,9 +84,10 @@ export class ExtHostDocuments implements ExtHostDocumentsShape {
|
||||
|
||||
let promise = this._documentLoader.get(uri.toString());
|
||||
if (!promise) {
|
||||
promise = this._proxy.$tryOpenDocument(uri).then(() => {
|
||||
promise = this._proxy.$tryOpenDocument(uri).then(uriData => {
|
||||
this._documentLoader.delete(uri.toString());
|
||||
return assertIsDefined(this._documentsAndEditors.getDocument(uri));
|
||||
const canonicalUri = URI.revive(uriData);
|
||||
return assertIsDefined(this._documentsAndEditors.getDocument(canonicalUri));
|
||||
}, err => {
|
||||
this._documentLoader.delete(uri.toString());
|
||||
return Promise.reject(err);
|
||||
|
||||
@@ -857,16 +857,11 @@ class SuggestAdapter {
|
||||
private _cache = new Cache<vscode.CompletionItem>('CompletionItem');
|
||||
private _disposables = new Map<number, DisposableStore>();
|
||||
|
||||
private _didWarnMust: boolean = false;
|
||||
private _didWarnShould: boolean = false;
|
||||
|
||||
constructor(
|
||||
private readonly _documents: ExtHostDocuments,
|
||||
private readonly _commands: CommandsConverter,
|
||||
private readonly _provider: vscode.CompletionItemProvider,
|
||||
private readonly _logService: ILogService,
|
||||
private readonly _apiDeprecation: IExtHostApiDeprecationService,
|
||||
private readonly _telemetry: extHostProtocol.MainThreadTelemetryShape,
|
||||
private readonly _extension: IExtensionDescription,
|
||||
) { }
|
||||
|
||||
@@ -930,41 +925,12 @@ class SuggestAdapter {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const _mustNotChange = SuggestAdapter._mustNotChangeHash(item);
|
||||
const _mayNotChange = SuggestAdapter._mayNotChangeHash(item);
|
||||
|
||||
const resolvedItem = await asPromise(() => this._provider.resolveCompletionItem!(item, token));
|
||||
|
||||
if (!resolvedItem) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
type BlameExtension = {
|
||||
extensionId: string;
|
||||
kind: string;
|
||||
index: string;
|
||||
};
|
||||
|
||||
type BlameExtensionMeta = {
|
||||
extensionId: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' };
|
||||
kind: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' };
|
||||
index: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth' };
|
||||
};
|
||||
|
||||
let _mustNotChangeIndex = !this._didWarnMust && SuggestAdapter._mustNotChangeDiff(_mustNotChange, resolvedItem);
|
||||
if (typeof _mustNotChangeIndex === 'string') {
|
||||
this._logService.warn(`[${this._extension.identifier.value}] INVALID result from 'resolveCompletionItem', extension MUST NOT change any of: label, sortText, filterText, insertText, or textEdit`);
|
||||
this._telemetry.$publicLog2<BlameExtension, BlameExtensionMeta>('badresolvecompletion', { extensionId: this._extension.identifier.value, kind: 'must', index: _mustNotChangeIndex });
|
||||
this._didWarnMust = true;
|
||||
}
|
||||
|
||||
let _mayNotChangeIndex = !this._didWarnShould && SuggestAdapter._mayNotChangeDiff(_mayNotChange, resolvedItem);
|
||||
if (typeof _mayNotChangeIndex === 'string') {
|
||||
this._logService.info(`[${this._extension.identifier.value}] UNSAVE result from 'resolveCompletionItem', extension SHOULD NOT change any of: additionalTextEdits, or command`);
|
||||
this._telemetry.$publicLog2<BlameExtension, BlameExtensionMeta>('badresolvecompletion', { extensionId: this._extension.identifier.value, kind: 'should', index: _mayNotChangeIndex });
|
||||
this._didWarnShould = true;
|
||||
}
|
||||
|
||||
return this._convertCompletionItem(resolvedItem, id);
|
||||
}
|
||||
|
||||
@@ -1035,45 +1001,6 @@ class SuggestAdapter {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static _mustNotChangeHash(item: vscode.CompletionItem) {
|
||||
const res = JSON.stringify([item.label, item.sortText, item.filterText, item.insertText, item.range]);
|
||||
return res;
|
||||
}
|
||||
|
||||
private static _mustNotChangeDiff(hash: string, item: vscode.CompletionItem): string | void {
|
||||
const thisArr = [item.label, item.sortText, item.filterText, item.insertText, item.range];
|
||||
const thisHash = JSON.stringify(thisArr);
|
||||
if (hash === thisHash) {
|
||||
return;
|
||||
}
|
||||
const arr = JSON.parse(hash);
|
||||
for (let i = 0; i < 6; i++) {
|
||||
if (JSON.stringify(arr[i] !== JSON.stringify(thisArr[i]))) {
|
||||
return i.toString();
|
||||
}
|
||||
}
|
||||
return 'unknown';
|
||||
}
|
||||
|
||||
private static _mayNotChangeHash(item: vscode.CompletionItem) {
|
||||
return JSON.stringify([item.additionalTextEdits, item.command]);
|
||||
}
|
||||
|
||||
private static _mayNotChangeDiff(hash: string, item: vscode.CompletionItem): string | void {
|
||||
const thisArr = [item.additionalTextEdits, item.command];
|
||||
const thisHash = JSON.stringify(thisArr);
|
||||
if (hash === thisHash) {
|
||||
return;
|
||||
}
|
||||
const arr = JSON.parse(hash);
|
||||
for (let i = 0; i < 6; i++) {
|
||||
if (JSON.stringify(arr[i] !== JSON.stringify(thisArr[i]))) {
|
||||
return i.toString();
|
||||
}
|
||||
}
|
||||
return 'unknown';
|
||||
}
|
||||
}
|
||||
|
||||
class SignatureHelpAdapter {
|
||||
@@ -1392,7 +1319,6 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
|
||||
private readonly _uriTransformer: IURITransformer | null;
|
||||
private readonly _proxy: extHostProtocol.MainThreadLanguageFeaturesShape;
|
||||
private readonly _telemetryShape: extHostProtocol.MainThreadTelemetryShape;
|
||||
private _documents: ExtHostDocuments;
|
||||
private _commands: ExtHostCommands;
|
||||
private _diagnostics: ExtHostDiagnostics;
|
||||
@@ -1411,7 +1337,6 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
) {
|
||||
this._uriTransformer = uriTransformer;
|
||||
this._proxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadLanguageFeatures);
|
||||
this._telemetryShape = mainContext.getProxy(extHostProtocol.MainContext.MainThreadTelemetry);
|
||||
this._documents = documents;
|
||||
this._commands = commands;
|
||||
this._diagnostics = diagnostics;
|
||||
@@ -1780,7 +1705,7 @@ export class ExtHostLanguageFeatures implements extHostProtocol.ExtHostLanguageF
|
||||
// --- suggestion
|
||||
|
||||
registerCompletionItemProvider(extension: IExtensionDescription, selector: vscode.DocumentSelector, provider: vscode.CompletionItemProvider, triggerCharacters: string[]): vscode.Disposable {
|
||||
const handle = this._addNewAdapter(new SuggestAdapter(this._documents, this._commands.converter, provider, this._logService, this._apiDeprecation, this._telemetryShape, extension), extension);
|
||||
const handle = this._addNewAdapter(new SuggestAdapter(this._documents, this._commands.converter, provider, this._apiDeprecation, extension), extension);
|
||||
this._proxy.$registerSuggestSupport(handle, this._transformDocumentSelector(selector), triggerCharacters, SuggestAdapter.supportsResolving(provider), extension.identifier);
|
||||
return this._createDisposable(handle);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
import { MainContext, MainThreadLanguagesShape, IMainContext } from './extHost.protocol';
|
||||
import type * as vscode from 'vscode';
|
||||
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
|
||||
import * as typeConvert from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { StandardTokenType, Range, Position } from 'vs/workbench/api/common/extHostTypes';
|
||||
|
||||
export class ExtHostLanguages {
|
||||
|
||||
@@ -32,4 +34,31 @@ export class ExtHostLanguages {
|
||||
}
|
||||
return data.document;
|
||||
}
|
||||
|
||||
async tokenAtPosition(document: vscode.TextDocument, position: vscode.Position): Promise<vscode.TokenInformation> {
|
||||
const versionNow = document.version;
|
||||
const pos = typeConvert.Position.from(position);
|
||||
const info = await this._proxy.$tokensAtPosition(document.uri, pos);
|
||||
const defaultRange = {
|
||||
type: StandardTokenType.Other,
|
||||
range: document.getWordRangeAtPosition(position) ?? new Range(position.line, position.character, position.line, position.character)
|
||||
};
|
||||
if (!info) {
|
||||
// no result
|
||||
return defaultRange;
|
||||
}
|
||||
const result = {
|
||||
range: typeConvert.Range.to(info.range),
|
||||
type: typeConvert.TokenType.to(info.type)
|
||||
};
|
||||
if (!result.range.contains(<Position>position)) {
|
||||
// bogous result
|
||||
return defaultRange;
|
||||
}
|
||||
if (versionNow !== document.version) {
|
||||
// concurrent change
|
||||
return defaultRange;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,16 @@ 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, INotebookDocumentsAndEditorsDelta } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { CellKind, 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, NotebookDataDto } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { Disposable as VSCodeDisposable } from './extHostTypes';
|
||||
import { CellEditType, CellUri, diff, ICellEditOperation, ICellInsertEdit, INotebookDisplayOrder, INotebookEditData, NotebookCellsChangedEvent, NotebookCellsSplice2, ICellDeleteEdit, notebookDocumentMetadataDefaults, NotebookCellsChangeType, NotebookDataDto, IOutputRenderRequest, IOutputRenderResponse, IOutputRenderResponseOutputInfo, IOutputRenderResponseCellInfo } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData';
|
||||
import { NotImplementedProxy } from 'vs/base/common/types';
|
||||
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
|
||||
|
||||
interface IObservable<T> {
|
||||
proxy: T;
|
||||
@@ -40,6 +42,12 @@ function getObservable<T extends Object>(obj: T): IObservable<T> {
|
||||
};
|
||||
}
|
||||
|
||||
interface INotebookEventEmitter {
|
||||
emitModelChange(events: vscode.NotebookCellsChangeEvent): void;
|
||||
emitCellOutputsChange(event: vscode.NotebookCellOutputsChangeEvent): void;
|
||||
emitCellLanguageChange(event: vscode.NotebookCellLanguageChangeEvent): void;
|
||||
}
|
||||
|
||||
export class ExtHostCell extends Disposable implements vscode.NotebookCell {
|
||||
|
||||
// private originalSource: string[];
|
||||
@@ -59,14 +67,17 @@ export class ExtHostCell extends Disposable implements vscode.NotebookCell {
|
||||
return this._documentData.document;
|
||||
}
|
||||
|
||||
get notebook(): vscode.NotebookDocument {
|
||||
return this._notebook;
|
||||
}
|
||||
|
||||
get source() {
|
||||
// todo@jrieken remove this
|
||||
return this._documentData.getText();
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly viewType: string,
|
||||
private readonly documentUri: URI,
|
||||
private readonly _notebook: ExtHostNotebookDocument,
|
||||
readonly handle: number,
|
||||
readonly uri: URI,
|
||||
content: string,
|
||||
@@ -133,7 +144,7 @@ export class ExtHostCell extends Disposable implements vscode.NotebookCell {
|
||||
}
|
||||
|
||||
private updateMetadata(): Promise<void> {
|
||||
return this._proxy.$updateNotebookCellMetadata(this.viewType, this.documentUri, this.handle, this._metadata);
|
||||
return this._proxy.$updateNotebookCellMetadata(this._notebook.viewType, this._notebook.uri, this.handle, this._metadata);
|
||||
}
|
||||
|
||||
attachTextDocument(document: ExtHostDocumentData) {
|
||||
@@ -217,9 +228,12 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||
return this._versionId;
|
||||
}
|
||||
|
||||
private _disposed = false;
|
||||
|
||||
constructor(
|
||||
private readonly _proxy: MainThreadNotebookShape,
|
||||
private _documentsAndEditors: ExtHostDocumentsAndEditors,
|
||||
private _emitter: INotebookEventEmitter,
|
||||
public viewType: string,
|
||||
public uri: URI,
|
||||
public renderingHandler: ExtHostNotebookOutputRenderingHandler
|
||||
@@ -238,6 +252,7 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._disposed = true;
|
||||
super.dispose();
|
||||
this._cellDisposableMapping.forEach(cell => cell.dispose());
|
||||
}
|
||||
@@ -246,7 +261,8 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||
|
||||
get isDirty() { return false; }
|
||||
|
||||
accpetModelChanged(event: NotebookCellsChangedEvent) {
|
||||
accpetModelChanged(event: NotebookCellsChangedEvent): void {
|
||||
this._versionId = event.versionId;
|
||||
if (event.kind === NotebookCellsChangeType.ModelChange) {
|
||||
this.$spliceNotebookCells(event.changes);
|
||||
} else if (event.kind === NotebookCellsChangeType.Move) {
|
||||
@@ -258,19 +274,19 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||
} else if (event.kind === NotebookCellsChangeType.ChangeLanguage) {
|
||||
this.$changeCellLanguage(event.index, event.language);
|
||||
}
|
||||
|
||||
this._versionId = event.versionId;
|
||||
}
|
||||
|
||||
private $spliceNotebookCells(splices: NotebookCellsSplice2[]): void {
|
||||
if (!splices.length) {
|
||||
if (this._disposed) {
|
||||
return;
|
||||
}
|
||||
|
||||
let contentChangeEvents: vscode.NotebookCellsChangeData[] = [];
|
||||
|
||||
splices.reverse().forEach(splice => {
|
||||
let cellDtos = splice[2];
|
||||
let newCells = cellDtos.map(cell => {
|
||||
const extCell = new ExtHostCell(this.viewType, this.uri, cell.handle, URI.revive(cell.uri), cell.source.join('\n'), cell.cellKind, cell.language, cell.outputs, cell.metadata, this._proxy);
|
||||
const extCell = new ExtHostCell(this, cell.handle, URI.revive(cell.uri), cell.source.join('\n'), cell.cellKind, cell.language, cell.outputs, cell.metadata, this._proxy);
|
||||
const documentData = this._documentsAndEditors.getDocument(URI.revive(cell.uri));
|
||||
|
||||
if (documentData) {
|
||||
@@ -297,107 +313,88 @@ export class ExtHostNotebookDocument extends Disposable implements vscode.Notebo
|
||||
}
|
||||
|
||||
this.cells.splice(splice[0], splice[1], ...newCells);
|
||||
|
||||
const event: vscode.NotebookCellsChangeData = {
|
||||
start: splice[0],
|
||||
deletedCount: splice[1],
|
||||
items: newCells
|
||||
};
|
||||
|
||||
contentChangeEvents.push(event);
|
||||
});
|
||||
|
||||
this._emitter.emitModelChange({
|
||||
document: this,
|
||||
changes: contentChangeEvents
|
||||
});
|
||||
}
|
||||
|
||||
private $moveCell(index: number, newIdx: number) {
|
||||
private $moveCell(index: number, newIdx: number): void {
|
||||
const cells = this.cells.splice(index, 1);
|
||||
this.cells.splice(newIdx, 0, ...cells);
|
||||
const changes: vscode.NotebookCellsChangeData[] = [{
|
||||
start: index,
|
||||
deletedCount: 1,
|
||||
items: []
|
||||
}, {
|
||||
start: newIdx,
|
||||
deletedCount: 0,
|
||||
items: cells
|
||||
}];
|
||||
this._emitter.emitModelChange({
|
||||
document: this,
|
||||
changes
|
||||
});
|
||||
}
|
||||
|
||||
private $clearCellOutputs(index: number) {
|
||||
private $clearCellOutputs(index: number): void {
|
||||
const cell = this.cells[index];
|
||||
cell.outputs = [];
|
||||
const event: vscode.NotebookCellOutputsChangeEvent = { document: this, cells: [cell] };
|
||||
this._emitter.emitCellOutputsChange(event);
|
||||
}
|
||||
|
||||
private $clearAllCellOutputs() {
|
||||
this.cells.forEach(cell => cell.outputs = []);
|
||||
private $clearAllCellOutputs(): void {
|
||||
const modifedCells: vscode.NotebookCell[] = [];
|
||||
this.cells.forEach(cell => {
|
||||
if (cell.outputs.length !== 0) {
|
||||
cell.outputs = [];
|
||||
modifedCells.push(cell);
|
||||
}
|
||||
});
|
||||
const event: vscode.NotebookCellOutputsChangeEvent = { document: this, cells: modifedCells };
|
||||
this._emitter.emitCellOutputsChange(event);
|
||||
}
|
||||
|
||||
private $changeCellLanguage(index: number, language: string) {
|
||||
private $changeCellLanguage(index: number, language: string): void {
|
||||
const cell = this.cells[index];
|
||||
cell.language = language;
|
||||
const event: vscode.NotebookCellLanguageChangeEvent = { document: this, cell, language };
|
||||
this._emitter.emitCellLanguageChange(event);
|
||||
}
|
||||
|
||||
eventuallyUpdateCellOutputs(cell: ExtHostCell, diffs: ISplice<vscode.CellOutput>[]) {
|
||||
async eventuallyUpdateCellOutputs(cell: ExtHostCell, diffs: ISplice<vscode.CellOutput>[]) {
|
||||
let renderers = new Set<number>();
|
||||
let outputDtos: NotebookCellOutputsSplice[] = diffs.map(diff => {
|
||||
let outputs = diff.toInsert;
|
||||
|
||||
let transformedOutputs = outputs.map(output => {
|
||||
if (output.outputKind === CellOutputKind.Rich) {
|
||||
const ret = this.transformMimeTypes(output);
|
||||
|
||||
if (ret.orderedMimeTypes[ret.pickedMimeTypeIndex].isResolved) {
|
||||
renderers.add(ret.orderedMimeTypes[ret.pickedMimeTypeIndex].rendererId!);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return output as IStreamOutput | IErrorOutput;
|
||||
}
|
||||
});
|
||||
|
||||
return [diff.start, diff.deleteCount, transformedOutputs];
|
||||
return [diff.start, diff.deleteCount, outputs];
|
||||
});
|
||||
|
||||
this._proxy.$spliceNotebookCellOutputs(this.viewType, this.uri, cell.handle, outputDtos, Array.from(renderers));
|
||||
}
|
||||
|
||||
transformMimeTypes(output: vscode.CellDisplayOutput): ITransformedDisplayOutputDto {
|
||||
let mimeTypes = Object.keys(output.data);
|
||||
let coreDisplayOrder = this.renderingHandler.outputDisplayOrder;
|
||||
const sorted = sortMimeTypes(mimeTypes, coreDisplayOrder?.userOrder || [], this._displayOrder, coreDisplayOrder?.defaultOrder || []);
|
||||
|
||||
let orderMimeTypes: IOrderedMimeType[] = [];
|
||||
|
||||
sorted.forEach(mimeType => {
|
||||
let handlers = this.renderingHandler.findBestMatchedRenderer(mimeType);
|
||||
|
||||
if (handlers.length) {
|
||||
let renderedOutput = handlers[0].render(this, output, mimeType);
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
await this._proxy.$spliceNotebookCellOutputs(this.viewType, this.uri, cell.handle, outputDtos, Array.from(renderers));
|
||||
this._emitter.emitCellOutputsChange({
|
||||
document: this,
|
||||
cells: [cell]
|
||||
});
|
||||
|
||||
return {
|
||||
outputKind: output.outputKind,
|
||||
data: output.data,
|
||||
orderedMimeTypes: orderMimeTypes,
|
||||
pickedMimeTypeIndex: 0
|
||||
};
|
||||
}
|
||||
|
||||
getCell(cellHandle: number) {
|
||||
return this.cells.find(cell => cell.handle === cellHandle);
|
||||
}
|
||||
|
||||
getCell2(cellUri: UriComponents) {
|
||||
return this.cells.find(cell => cell.uri.fragment === cellUri.fragment);
|
||||
}
|
||||
|
||||
attachCellTextDocument(textDocument: ExtHostDocumentData) {
|
||||
let cell = this.cells.find(cell => cell.uri.toString() === textDocument.document.uri.toString());
|
||||
if (cell) {
|
||||
@@ -448,25 +445,10 @@ export class NotebookEditorCellEditBuilder implements vscode.NotebookEditorCellE
|
||||
source: sourceArr,
|
||||
language,
|
||||
cellKind: type,
|
||||
outputs: (outputs as any[]), // TODO@rebornix
|
||||
outputs: outputs,
|
||||
metadata
|
||||
};
|
||||
|
||||
const transformedOutputs = outputs.map(output => {
|
||||
if (output.outputKind === CellOutputKind.Rich) {
|
||||
const ret = this.editor.document.transformMimeTypes(output);
|
||||
|
||||
if (ret.orderedMimeTypes[ret.pickedMimeTypeIndex].isResolved) {
|
||||
this._renderers.add(ret.orderedMimeTypes[ret.pickedMimeTypeIndex].rendererId!);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return output as IStreamOutput | IErrorOutput;
|
||||
}
|
||||
});
|
||||
|
||||
cell.outputs = transformedOutputs;
|
||||
|
||||
this._collectedEdits.push({
|
||||
editType: CellEditType.Insert,
|
||||
index,
|
||||
@@ -489,6 +471,35 @@ export class ExtHostNotebookEditor extends Disposable implements vscode.Notebook
|
||||
private _viewColumn: vscode.ViewColumn | undefined;
|
||||
|
||||
selection?: ExtHostCell = undefined;
|
||||
|
||||
private _active: boolean = false;
|
||||
get active(): boolean {
|
||||
return this._active;
|
||||
}
|
||||
|
||||
set active(_state: boolean) {
|
||||
throw readonly('active');
|
||||
}
|
||||
|
||||
private _visible: boolean = false;
|
||||
get visible(): boolean {
|
||||
return this._visible;
|
||||
}
|
||||
|
||||
set visible(_state: boolean) {
|
||||
throw readonly('visible');
|
||||
}
|
||||
|
||||
_acceptVisibility(value: boolean) {
|
||||
this._visible = value;
|
||||
}
|
||||
|
||||
_acceptActive(value: boolean) {
|
||||
this._active = value;
|
||||
}
|
||||
|
||||
private _onDidDispose = new Emitter<void>();
|
||||
readonly onDidDispose: Event<void> = this._onDidDispose.event;
|
||||
onDidReceiveMessage: vscode.Event<any> = this._onDidReceiveMessage.event;
|
||||
|
||||
constructor(
|
||||
@@ -497,6 +508,7 @@ export class ExtHostNotebookEditor extends Disposable implements vscode.Notebook
|
||||
public uri: URI,
|
||||
private _proxy: MainThreadNotebookShape,
|
||||
private _onDidReceiveMessage: Emitter<any>,
|
||||
private _webviewInitData: WebviewInitData,
|
||||
public document: ExtHostNotebookDocument,
|
||||
private _documentsAndEditors: ExtHostDocumentsAndEditors
|
||||
) {
|
||||
@@ -584,6 +596,13 @@ export class ExtHostNotebookEditor extends Disposable implements vscode.Notebook
|
||||
return this._proxy.$postMessage(this.document.handle, message);
|
||||
}
|
||||
|
||||
asWebviewUri(localResource: vscode.Uri): vscode.Uri {
|
||||
return asWebviewUri(this._webviewInitData, this.id, localResource);
|
||||
}
|
||||
dispose() {
|
||||
this._onDidDispose.fire();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostNotebookOutputRenderer {
|
||||
@@ -620,16 +639,21 @@ export interface ExtHostNotebookOutputRenderingHandler {
|
||||
}
|
||||
|
||||
export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostNotebookOutputRenderingHandler {
|
||||
private static _handlePool: number = 0;
|
||||
|
||||
private readonly _proxy: MainThreadNotebookShape;
|
||||
private readonly _notebookContentProviders = new Map<string, { readonly provider: vscode.NotebookContentProvider, readonly extension: IExtensionDescription; }>();
|
||||
private readonly _notebookKernels = new Map<string, { readonly kernel: vscode.NotebookKernel, readonly extension: IExtensionDescription; }>();
|
||||
private readonly _documents = new Map<string, ExtHostNotebookDocument>();
|
||||
private readonly _unInitializedDocuments = new Map<string, ExtHostNotebookDocument>();
|
||||
private readonly _editors = new Map<string, { editor: ExtHostNotebookEditor, onDidReceiveMessage: Emitter<any>; }>();
|
||||
private readonly _notebookOutputRenderers = new Map<number, ExtHostNotebookOutputRenderer>();
|
||||
|
||||
private readonly _onDidChangeNotebookDocument = new Emitter<{ document: ExtHostNotebookDocument, changes: NotebookCellsChangedEvent[]; }>();
|
||||
readonly onDidChangeNotebookDocument: Event<{ document: ExtHostNotebookDocument, changes: NotebookCellsChangedEvent[]; }> = this._onDidChangeNotebookDocument.event;
|
||||
private readonly _notebookOutputRenderers = new Map<string, ExtHostNotebookOutputRenderer>();
|
||||
private readonly _onDidChangeNotebookCells = new Emitter<vscode.NotebookCellsChangeEvent>();
|
||||
readonly onDidChangeNotebookCells = this._onDidChangeNotebookCells.event;
|
||||
private readonly _onDidChangeCellOutputs = new Emitter<vscode.NotebookCellOutputsChangeEvent>();
|
||||
readonly onDidChangeCellOutputs = this._onDidChangeCellOutputs.event;
|
||||
private readonly _onDidChangeCellLanguage = new Emitter<vscode.NotebookCellLanguageChangeEvent>();
|
||||
readonly onDidChangeCellLanguage = this._onDidChangeCellLanguage.event;
|
||||
private readonly _onDidChangeActiveNotebookEditor = new Emitter<vscode.NotebookEditor | undefined>();
|
||||
readonly onDidChangeActiveNotebookEditor = this._onDidChangeActiveNotebookEditor.event;
|
||||
|
||||
private _outputDisplayOrder: INotebookDisplayOrder | undefined;
|
||||
|
||||
@@ -653,8 +677,11 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
onDidOpenNotebookDocument: Event<vscode.NotebookDocument> = this._onDidOpenNotebookDocument.event;
|
||||
private _onDidCloseNotebookDocument = new Emitter<vscode.NotebookDocument>();
|
||||
onDidCloseNotebookDocument: Event<vscode.NotebookDocument> = this._onDidCloseNotebookDocument.event;
|
||||
visibleNotebookEditors: ExtHostNotebookEditor[] = [];
|
||||
private _onDidChangeVisibleNotebookEditors = new Emitter<vscode.NotebookEditor[]>();
|
||||
onDidChangeVisibleNotebookEditors = this._onDidChangeVisibleNotebookEditors.event;
|
||||
|
||||
constructor(mainContext: IMainContext, commands: ExtHostCommands, private _documentsAndEditors: ExtHostDocumentsAndEditors) {
|
||||
constructor(mainContext: IMainContext, commands: ExtHostCommands, private _documentsAndEditors: ExtHostDocumentsAndEditors, private readonly _webviewInitData: WebviewInitData) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadNotebook);
|
||||
|
||||
commands.registerArgumentProcessor({
|
||||
@@ -683,15 +710,85 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
filter: vscode.NotebookOutputSelector,
|
||||
renderer: vscode.NotebookOutputRenderer
|
||||
): vscode.Disposable {
|
||||
if (this._notebookKernels.has(type)) {
|
||||
throw new Error(`Notebook renderer for '${type}' already registered`);
|
||||
}
|
||||
|
||||
let extHostRenderer = new ExtHostNotebookOutputRenderer(type, filter, renderer);
|
||||
this._notebookOutputRenderers.set(extHostRenderer.handle, extHostRenderer);
|
||||
this._proxy.$registerNotebookRenderer({ id: extension.identifier, location: extension.extensionLocation }, type, filter, extHostRenderer.handle, renderer.preloads || []);
|
||||
return new VSCodeDisposable(() => {
|
||||
this._notebookOutputRenderers.delete(extHostRenderer.handle);
|
||||
this._proxy.$unregisterNotebookRenderer(extHostRenderer.handle);
|
||||
this._notebookOutputRenderers.set(extHostRenderer.type, extHostRenderer);
|
||||
this._proxy.$registerNotebookRenderer({ id: extension.identifier, location: extension.extensionLocation }, type, filter, renderer.preloads || []);
|
||||
return new extHostTypes.Disposable(() => {
|
||||
this._notebookOutputRenderers.delete(extHostRenderer.type);
|
||||
this._proxy.$unregisterNotebookRenderer(extHostRenderer.type);
|
||||
});
|
||||
}
|
||||
|
||||
async $renderOutputs(uriComponents: UriComponents, id: string, request: IOutputRenderRequest<UriComponents>): Promise<IOutputRenderResponse<UriComponents> | undefined> {
|
||||
if (!this._notebookOutputRenderers.has(id)) {
|
||||
throw new Error(`Notebook renderer for '${id}' is not registered`);
|
||||
}
|
||||
|
||||
const document = this._documents.get(URI.revive(uriComponents).toString());
|
||||
|
||||
if (!document) {
|
||||
return undefined; // {{SQL CARBON EDIT}} strict-null-checks
|
||||
}
|
||||
|
||||
const renderer = this._notebookOutputRenderers.get(id)!;
|
||||
const cellsResponse: IOutputRenderResponseCellInfo<UriComponents>[] = request.items.map(cellInfo => {
|
||||
const cell = document.getCell2(cellInfo.key);
|
||||
const outputResponse: IOutputRenderResponseOutputInfo[] = cellInfo.outputs.map(output => {
|
||||
return {
|
||||
index: output.index,
|
||||
mimeType: output.mimeType,
|
||||
handlerId: id,
|
||||
transformedOutput: renderer.render(document, cell!.outputs[output.index] as vscode.CellDisplayOutput, output.mimeType)
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
key: cellInfo.key,
|
||||
outputs: outputResponse
|
||||
};
|
||||
});
|
||||
|
||||
return { items: cellsResponse };
|
||||
}
|
||||
|
||||
/**
|
||||
* The request carry the raw data for outputs so we don't look up in the existing document
|
||||
*/
|
||||
async $renderOutputs2<T>(uriComponents: UriComponents, id: string, request: IOutputRenderRequest<T>): Promise<IOutputRenderResponse<T> | undefined> {
|
||||
if (!this._notebookOutputRenderers.has(id)) {
|
||||
throw new Error(`Notebook renderer for '${id}' is not registered`);
|
||||
}
|
||||
|
||||
const document = this._documents.get(URI.revive(uriComponents).toString());
|
||||
|
||||
if (!document) {
|
||||
return undefined; // {{SQL CARBON EDIT}} strict-null-checks
|
||||
}
|
||||
|
||||
const renderer = this._notebookOutputRenderers.get(id)!;
|
||||
const cellsResponse: IOutputRenderResponseCellInfo<T>[] = request.items.map(cellInfo => {
|
||||
const outputResponse: IOutputRenderResponseOutputInfo[] = cellInfo.outputs.map(output => {
|
||||
return {
|
||||
index: output.index,
|
||||
mimeType: output.mimeType,
|
||||
handlerId: id,
|
||||
transformedOutput: renderer.render(document, output.output! as vscode.CellDisplayOutput, output.mimeType)
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
key: cellInfo.key,
|
||||
outputs: outputResponse
|
||||
};
|
||||
});
|
||||
|
||||
return { items: cellsResponse };
|
||||
}
|
||||
|
||||
findBestMatchedRenderer(mimeType: string): ExtHostNotebookOutputRenderer[] {
|
||||
let matches: ExtHostNotebookOutputRenderer[] = [];
|
||||
for (let renderer of this._notebookOutputRenderers) {
|
||||
@@ -713,50 +810,70 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
throw new Error(`Notebook provider for '${viewType}' already registered`);
|
||||
}
|
||||
|
||||
// if ((<any>provider).executeCell) {
|
||||
// throw new Error('NotebookContentKernel.executeCell is removed, please use vscode.notebook.registerNotebookKernel instead.');
|
||||
// }
|
||||
|
||||
this._notebookContentProviders.set(viewType, { extension, provider });
|
||||
this._proxy.$registerNotebookProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType);
|
||||
return new VSCodeDisposable(() => {
|
||||
|
||||
const listener = provider.onDidChangeNotebook
|
||||
? provider.onDidChangeNotebook(e => this._proxy.$onNotebookChange(viewType, e.document.uri))
|
||||
: Disposable.None;
|
||||
|
||||
this._proxy.$registerNotebookProvider({ id: extension.identifier, location: extension.extensionLocation }, viewType, provider.kernel ? { id: viewType, label: provider.kernel.label, extensionLocation: extension.extensionLocation, preloads: provider.kernel.preloads } : undefined);
|
||||
return new extHostTypes.Disposable(() => {
|
||||
listener.dispose();
|
||||
this._notebookContentProviders.delete(viewType);
|
||||
this._proxy.$unregisterNotebookProvider(viewType);
|
||||
});
|
||||
}
|
||||
|
||||
async $resolveNotebookData(viewType: string, uri: UriComponents): Promise<NotebookDataDto | undefined> {
|
||||
let provider = this._notebookContentProviders.get(viewType);
|
||||
let document = this._documents.get(URI.revive(uri).toString());
|
||||
registerNotebookKernel(extension: IExtensionDescription, id: string, selectors: vscode.GlobPattern[], kernel: vscode.NotebookKernel): vscode.Disposable {
|
||||
if (this._notebookKernels.has(id)) {
|
||||
throw new Error(`Notebook kernel for '${id}' already registered`);
|
||||
}
|
||||
|
||||
this._notebookKernels.set(id, { kernel, extension });
|
||||
const transformedSelectors = selectors.map(selector => typeConverters.GlobPattern.from(selector));
|
||||
|
||||
this._proxy.$registerNotebookKernel({ id: extension.identifier, location: extension.extensionLocation }, id, kernel.label, transformedSelectors, kernel.preloads || []);
|
||||
return new extHostTypes.Disposable(() => {
|
||||
this._notebookKernels.delete(id);
|
||||
this._proxy.$unregisterNotebookKernel(id);
|
||||
});
|
||||
}
|
||||
|
||||
async $resolveNotebookData(viewType: string, uri: UriComponents): Promise<NotebookDataDto | undefined> {
|
||||
const provider = this._notebookContentProviders.get(viewType);
|
||||
const revivedUri = URI.revive(uri);
|
||||
|
||||
if (provider) {
|
||||
let document = this._documents.get(URI.revive(uri).toString());
|
||||
|
||||
if (!document) {
|
||||
const that = this;
|
||||
document = this._unInitializedDocuments.get(revivedUri.toString()) ?? new ExtHostNotebookDocument(this._proxy, this._documentsAndEditors, {
|
||||
emitModelChange(event: vscode.NotebookCellsChangeEvent): void {
|
||||
that._onDidChangeNotebookCells.fire(event);
|
||||
},
|
||||
emitCellOutputsChange(event: vscode.NotebookCellOutputsChangeEvent): void {
|
||||
that._onDidChangeCellOutputs.fire(event);
|
||||
},
|
||||
emitCellLanguageChange(event: vscode.NotebookCellLanguageChangeEvent): void {
|
||||
that._onDidChangeCellLanguage.fire(event);
|
||||
}
|
||||
}, viewType, revivedUri, this);
|
||||
this._unInitializedDocuments.set(revivedUri.toString(), document);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (ret.orderedMimeTypes[ret.pickedMimeTypeIndex].isResolved) {
|
||||
renderers.add(ret.orderedMimeTypes[ret.pickedMimeTypeIndex].rendererId!);
|
||||
}
|
||||
return ret;
|
||||
} else {
|
||||
return output as IStreamOutput | IErrorOutput;
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
language: cell.language,
|
||||
cellKind: cell.cellKind,
|
||||
metadata: cell.metadata,
|
||||
source: cell.source,
|
||||
outputs: transformedOutputs
|
||||
};
|
||||
})
|
||||
cells: rawCells.cells,
|
||||
};
|
||||
|
||||
return dto;
|
||||
@@ -765,58 +882,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
return undefined; // {{SQL CARBON EDIT}}
|
||||
}
|
||||
|
||||
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 || []);
|
||||
|
||||
let orderMimeTypes: IOrderedMimeType[] = [];
|
||||
|
||||
sorted.forEach(mimeType => {
|
||||
let handlers = this.findBestMatchedRenderer(mimeType);
|
||||
|
||||
if (handlers.length) {
|
||||
let renderedOutput = handlers[0].render(document, output, mimeType);
|
||||
|
||||
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
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
outputKind: output.outputKind,
|
||||
data: output.data,
|
||||
orderedMimeTypes: orderMimeTypes,
|
||||
pickedMimeTypeIndex: 0
|
||||
};
|
||||
}
|
||||
|
||||
async $executeNotebook(viewType: string, uri: UriComponents, cellHandle: number | undefined, token: CancellationToken): Promise<void> {
|
||||
async $executeNotebook(viewType: string, uri: UriComponents, cellHandle: number | undefined, useAttachedKernel: boolean, token: CancellationToken): Promise<void> {
|
||||
let document = this._documents.get(URI.revive(uri).toString());
|
||||
|
||||
if (!document) {
|
||||
@@ -824,9 +890,38 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
}
|
||||
|
||||
if (this._notebookContentProviders.has(viewType)) {
|
||||
let cell = cellHandle !== undefined ? document.getCell(cellHandle) : undefined;
|
||||
const cell = cellHandle !== undefined ? document.getCell(cellHandle) : undefined;
|
||||
const provider = this._notebookContentProviders.get(viewType)!.provider;
|
||||
|
||||
return this._notebookContentProviders.get(viewType)!.provider.executeCell(document, cell, token);
|
||||
if (provider.kernel && useAttachedKernel) {
|
||||
if (cell) {
|
||||
return provider.kernel.executeCell(document, cell, token);
|
||||
} else {
|
||||
return provider.kernel.executeAllCells(document, token);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async $executeNotebook2(kernelId: string, viewType: string, uri: UriComponents, cellHandle: number | undefined, token: CancellationToken): Promise<void> {
|
||||
let document = this._documents.get(URI.revive(uri).toString());
|
||||
|
||||
if (!document || document.viewType !== viewType) {
|
||||
return;
|
||||
}
|
||||
|
||||
let kernelInfo = this._notebookKernels.get(kernelId);
|
||||
|
||||
if (!kernelInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
let cell = cellHandle !== undefined ? document.getCell(cellHandle) : undefined;
|
||||
|
||||
if (cell) {
|
||||
return kernelInfo.kernel.executeCell(document, cell, token);
|
||||
} else {
|
||||
return kernelInfo.kernel.executeAllCells(document, token);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -872,8 +967,21 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
this._outputDisplayOrder = displayOrder;
|
||||
}
|
||||
|
||||
$onDidReceiveMessage(uri: UriComponents, message: any): void {
|
||||
let editor = this._editors.get(URI.revive(uri).toString());
|
||||
// TODO: remove document - editor one on one mapping
|
||||
private _getEditorFromURI(uriComponents: UriComponents) {
|
||||
const uriStr = URI.revive(uriComponents).toString();
|
||||
let editor: { editor: ExtHostNotebookEditor, onDidReceiveMessage: Emitter<any>; } | undefined;
|
||||
this._editors.forEach(e => {
|
||||
if (e.editor.uri.toString() === uriStr) {
|
||||
editor = e;
|
||||
}
|
||||
});
|
||||
|
||||
return editor;
|
||||
}
|
||||
|
||||
$onDidReceiveMessage(editorId: string, message: any): void {
|
||||
let editor = this._editors.get(editorId);
|
||||
|
||||
if (editor) {
|
||||
editor.onDidReceiveMessage.fire(message);
|
||||
@@ -881,20 +989,15 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
}
|
||||
|
||||
$acceptModelChanged(uriComponents: UriComponents, event: NotebookCellsChangedEvent): void {
|
||||
let editor = this._editors.get(URI.revive(uriComponents).toString());
|
||||
const document = this._documents.get(URI.revive(uriComponents).toString());
|
||||
|
||||
if (editor) {
|
||||
editor.editor.document.accpetModelChanged(event);
|
||||
this._onDidChangeNotebookDocument.fire({
|
||||
document: editor.editor.document,
|
||||
changes: [event]
|
||||
});
|
||||
if (document) {
|
||||
document.accpetModelChanged(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$acceptEditorPropertiesChanged(uriComponents: UriComponents, data: INotebookEditorPropertiesChangeData): void {
|
||||
let editor = this._editors.get(URI.revive(uriComponents).toString());
|
||||
let editor = this._getEditorFromURI(uriComponents);
|
||||
|
||||
if (!editor) {
|
||||
return;
|
||||
@@ -910,61 +1013,196 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
editor.editor.selection = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.metadata) {
|
||||
editor.editor.document.metadata = {
|
||||
...notebookDocumentMetadataDefaults,
|
||||
...data.metadata
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private _createExtHostEditor(document: ExtHostNotebookDocument, editorId: string, selections: number[]) {
|
||||
const onDidReceiveMessage = new Emitter<any>();
|
||||
const revivedUri = document.uri;
|
||||
|
||||
let editor = new ExtHostNotebookEditor(
|
||||
document.viewType,
|
||||
editorId,
|
||||
revivedUri,
|
||||
this._proxy,
|
||||
onDidReceiveMessage,
|
||||
this._webviewInitData,
|
||||
document,
|
||||
this._documentsAndEditors
|
||||
);
|
||||
|
||||
const cells = editor.document.cells;
|
||||
|
||||
if (selections.length) {
|
||||
const firstCell = selections[0];
|
||||
editor.selection = cells.find(cell => cell.handle === firstCell);
|
||||
} else {
|
||||
editor.selection = undefined;
|
||||
}
|
||||
|
||||
this._editors.get(editorId)?.editor.dispose();
|
||||
|
||||
this._editors.set(editorId, { editor, onDidReceiveMessage });
|
||||
}
|
||||
|
||||
async $acceptDocumentAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta) {
|
||||
let editorChanged = false;
|
||||
|
||||
if (delta.removedDocuments) {
|
||||
delta.removedDocuments.forEach((uri) => {
|
||||
let document = this._documents.get(URI.revive(uri).toString());
|
||||
const revivedUri = URI.revive(uri);
|
||||
const revivedUriStr = revivedUri.toString();
|
||||
let document = this._documents.get(revivedUriStr);
|
||||
|
||||
if (document) {
|
||||
document.dispose();
|
||||
this._documents.delete(URI.revive(uri).toString());
|
||||
this._documents.delete(revivedUriStr);
|
||||
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());
|
||||
}
|
||||
[...this._editors.values()].forEach((e) => {
|
||||
if (e.editor.uri.toString() === revivedUriStr) {
|
||||
e.editor.dispose();
|
||||
e.onDidReceiveMessage.dispose();
|
||||
this._editors.delete(e.editor.id);
|
||||
editorChanged = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (delta.addedDocuments) {
|
||||
delta.addedDocuments.forEach(modelData => {
|
||||
const revivedUri = URI.revive(modelData.uri);
|
||||
const revivedUriStr = revivedUri.toString();
|
||||
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);
|
||||
if (!this._documents.has(revivedUriStr)) {
|
||||
const that = this;
|
||||
let document = this._unInitializedDocuments.get(revivedUriStr) ?? new ExtHostNotebookDocument(this._proxy, this._documentsAndEditors, {
|
||||
emitModelChange(event: vscode.NotebookCellsChangeEvent): void {
|
||||
that._onDidChangeNotebookCells.fire(event);
|
||||
},
|
||||
emitCellOutputsChange(event: vscode.NotebookCellOutputsChangeEvent): void {
|
||||
that._onDidChangeCellOutputs.fire(event);
|
||||
},
|
||||
emitCellLanguageChange(event: vscode.NotebookCellLanguageChangeEvent): void {
|
||||
that._onDidChangeCellLanguage.fire(event);
|
||||
}
|
||||
}, viewType, revivedUri, this);
|
||||
|
||||
this._unInitializedDocuments.delete(revivedUriStr);
|
||||
if (modelData.metadata) {
|
||||
document.metadata = {
|
||||
...notebookDocumentMetadataDefaults,
|
||||
...modelData.metadata
|
||||
};
|
||||
}
|
||||
|
||||
document.accpetModelChanged({
|
||||
kind: NotebookCellsChangeType.ModelChange,
|
||||
versionId: modelData.versionId,
|
||||
changes: [[
|
||||
0,
|
||||
0,
|
||||
modelData.cells
|
||||
]]
|
||||
});
|
||||
|
||||
this._documents.get(revivedUriStr)?.dispose();
|
||||
this._documents.set(revivedUriStr, document);
|
||||
|
||||
// create editor if populated
|
||||
if (modelData.attachedEditor) {
|
||||
this._createExtHostEditor(document, modelData.attachedEditor.id, modelData.attachedEditor.selections);
|
||||
editorChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
);
|
||||
|
||||
const document = this._documents.get(revivedUriStr)!;
|
||||
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;
|
||||
if (delta.addedEditors) {
|
||||
delta.addedEditors.forEach(editorModelData => {
|
||||
if (this._editors.has(editorModelData.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const revivedUri = URI.revive(editorModelData.documentUri);
|
||||
const document = this._documents.get(revivedUri.toString());
|
||||
|
||||
if (document) {
|
||||
this._createExtHostEditor(document, editorModelData.id, editorModelData.selections);
|
||||
editorChanged = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const removedEditors: { editor: ExtHostNotebookEditor, onDidReceiveMessage: Emitter<any>; }[] = [];
|
||||
|
||||
if (delta.removedEditors) {
|
||||
delta.removedEditors.forEach(editorid => {
|
||||
const editor = this._editors.get(editorid);
|
||||
|
||||
if (editor) {
|
||||
editorChanged = true;
|
||||
this._editors.delete(editorid);
|
||||
|
||||
if (this.activeNotebookEditor?.id === editor.editor.id) {
|
||||
this._activeNotebookEditor = undefined;
|
||||
this._activeNotebookDocument = undefined;
|
||||
}
|
||||
|
||||
removedEditors.push(editor);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (editorChanged) {
|
||||
removedEditors.forEach(e => {
|
||||
e.editor.dispose();
|
||||
e.onDidReceiveMessage.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
if (delta.visibleEditors) {
|
||||
this.visibleNotebookEditors = delta.visibleEditors.map(id => this._editors.get(id)?.editor).filter(editor => !!editor) as ExtHostNotebookEditor[];
|
||||
const visibleEditorsSet = new Set<string>();
|
||||
this.visibleNotebookEditors.forEach(editor => visibleEditorsSet.add(editor.id));
|
||||
|
||||
[...this._editors.values()].forEach((e) => {
|
||||
const newValue = visibleEditorsSet.has(e.editor.id);
|
||||
e.editor._acceptVisibility(newValue);
|
||||
});
|
||||
|
||||
this.visibleNotebookEditors = [...this._editors.values()].map(e => e.editor).filter(e => e.visible);
|
||||
this._onDidChangeVisibleNotebookEditors.fire(this.visibleNotebookEditors);
|
||||
}
|
||||
|
||||
if (delta.newActiveEditor !== undefined) {
|
||||
if (delta.newActiveEditor) {
|
||||
this._activeNotebookEditor = this._editors.get(delta.newActiveEditor)?.editor;
|
||||
this._activeNotebookEditor?._acceptActive(true);
|
||||
this._activeNotebookDocument = this._activeNotebookEditor ? this._documents.get(this._activeNotebookEditor!.uri.toString()) : undefined;
|
||||
} else {
|
||||
this._activeNotebookEditor = undefined;
|
||||
this._activeNotebookDocument = undefined;
|
||||
}
|
||||
|
||||
this._onDidChangeActiveNotebookEditor.fire(this._activeNotebookEditor);
|
||||
}
|
||||
|
||||
[...this._editors.values()].forEach((e) => {
|
||||
if (e.editor !== this.activeNotebookEditor) {
|
||||
e.editor._acceptActive(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,13 +44,17 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
|
||||
this._onDidChange.fire(undefined);
|
||||
}
|
||||
}));
|
||||
this._disposables.add(extHostNotebooks.onDidChangeNotebookDocument(e => {
|
||||
if (e.document === this._notebook) {
|
||||
const documentChange = (document: vscode.NotebookDocument) => {
|
||||
if (document === this._notebook) {
|
||||
this._init();
|
||||
this._versionId += 1;
|
||||
this._onDidChange.fire(undefined);
|
||||
}
|
||||
}));
|
||||
};
|
||||
|
||||
this._disposables.add(extHostNotebooks.onDidChangeCellLanguage(e => documentChange(e.document)));
|
||||
this._disposables.add(extHostNotebooks.onDidChangeCellOutputs(e => documentChange(e.document)));
|
||||
this._disposables.add(extHostNotebooks.onDidChangeNotebookCells(e => documentChange(e.document)));
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
||||
@@ -35,8 +35,9 @@ export class ExtHostStatusBarEntry implements vscode.StatusBarItem {
|
||||
private _timeoutHandle: any;
|
||||
private _proxy: MainThreadStatusBarShape;
|
||||
private _commands: CommandsConverter;
|
||||
private _accessibilityInformation?: vscode.AccessibilityInformation;
|
||||
|
||||
constructor(proxy: MainThreadStatusBarShape, commands: CommandsConverter, id: string, name: string, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number) {
|
||||
constructor(proxy: MainThreadStatusBarShape, commands: CommandsConverter, id: string, name: string, alignment: ExtHostStatusBarAlignment = ExtHostStatusBarAlignment.Left, priority?: number, accessibilityInformation?: vscode.AccessibilityInformation) {
|
||||
this._id = ExtHostStatusBarEntry.ID_GEN++;
|
||||
this._proxy = proxy;
|
||||
this._commands = commands;
|
||||
@@ -44,6 +45,7 @@ export class ExtHostStatusBarEntry implements vscode.StatusBarItem {
|
||||
this._statusName = name;
|
||||
this._alignment = alignment;
|
||||
this._priority = priority;
|
||||
this._accessibilityInformation = accessibilityInformation;
|
||||
}
|
||||
|
||||
public get id(): number {
|
||||
@@ -74,6 +76,10 @@ export class ExtHostStatusBarEntry implements vscode.StatusBarItem {
|
||||
return this._command?.fromApi;
|
||||
}
|
||||
|
||||
public get accessibilityInformation(): vscode.AccessibilityInformation | undefined {
|
||||
return this._accessibilityInformation;
|
||||
}
|
||||
|
||||
public set text(text: string) {
|
||||
this._text = text;
|
||||
this.update();
|
||||
@@ -136,7 +142,7 @@ export class ExtHostStatusBarEntry implements vscode.StatusBarItem {
|
||||
// Set to status bar
|
||||
this._proxy.$setEntry(this.id, this._statusId, this._statusName, this.text, this.tooltip, this._command?.internal, this.color,
|
||||
this._alignment === ExtHostStatusBarAlignment.Left ? MainThreadStatusBarAlignment.LEFT : MainThreadStatusBarAlignment.RIGHT,
|
||||
this._priority);
|
||||
this._priority, this._accessibilityInformation);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
@@ -196,8 +202,8 @@ export class ExtHostStatusBar {
|
||||
this._statusMessage = new StatusBarMessage(this);
|
||||
}
|
||||
|
||||
createStatusBarEntry(id: string, name: string, alignment?: ExtHostStatusBarAlignment, priority?: number): vscode.StatusBarItem {
|
||||
return new ExtHostStatusBarEntry(this._proxy, this._commands, id, name, alignment, priority);
|
||||
createStatusBarEntry(id: string, name: string, alignment?: ExtHostStatusBarAlignment, priority?: number, accessibilityInformation?: vscode.AccessibilityInformation): vscode.StatusBarItem {
|
||||
return new ExtHostStatusBarEntry(this._proxy, this._commands, id, name, alignment, priority, accessibilityInformation);
|
||||
}
|
||||
|
||||
setStatusBarMessage(text: string, timeoutOrThenable?: number | Thenable<any>): Disposable {
|
||||
|
||||
@@ -384,6 +384,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
|
||||
protected _handleCounter: number;
|
||||
protected _handlers: Map<number, HandlerData>;
|
||||
protected _taskExecutions: Map<string, TaskExecutionImpl>;
|
||||
protected _taskExecutionPromises: Map<string, Promise<TaskExecutionImpl>>;
|
||||
protected _providedCustomExecutions2: Map<string, types.CustomExecution>;
|
||||
private _notProvidedCustomExecutions: Set<string>; // Used for custom executions tasks that are created and run through executeTask.
|
||||
protected _activeCustomExecutions2: Map<string, types.CustomExecution>;
|
||||
@@ -412,6 +413,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
|
||||
this._handleCounter = 0;
|
||||
this._handlers = new Map<number, HandlerData>();
|
||||
this._taskExecutions = new Map<string, TaskExecutionImpl>();
|
||||
this._taskExecutionPromises = new Map<string, Promise<TaskExecutionImpl>>();
|
||||
this._providedCustomExecutions2 = new Map<string, types.CustomExecution>();
|
||||
this._notProvidedCustomExecutions = new Set<string>();
|
||||
this._activeCustomExecutions2 = new Map<string, types.CustomExecution>();
|
||||
@@ -496,6 +498,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
|
||||
|
||||
public async $OnDidEndTask(execution: tasks.TaskExecutionDTO): Promise<void> {
|
||||
const _execution = await this.getTaskExecution(execution);
|
||||
this._taskExecutionPromises.delete(execution.id);
|
||||
this._taskExecutions.delete(execution.id);
|
||||
this.customExecutionComplete(execution);
|
||||
this._onDidTerminateTask.fire({
|
||||
@@ -626,17 +629,24 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
|
||||
return taskExecution;
|
||||
}
|
||||
|
||||
let result: TaskExecutionImpl | undefined = this._taskExecutions.get(execution.id);
|
||||
let result: Promise<TaskExecutionImpl> | undefined = this._taskExecutionPromises.get(execution.id);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
const taskToCreate = task ? task : await TaskDTO.to(execution.task, this._workspaceProvider);
|
||||
if (!taskToCreate) {
|
||||
throw new Error('Unexpected: Task does not exist.');
|
||||
}
|
||||
const createdResult: TaskExecutionImpl = new TaskExecutionImpl(this, execution.id, taskToCreate);
|
||||
this._taskExecutions.set(execution.id, createdResult);
|
||||
return createdResult;
|
||||
const createdResult: Promise<TaskExecutionImpl> = new Promise(async (resolve, reject) => {
|
||||
const taskToCreate = task ? task : await TaskDTO.to(execution.task, this._workspaceProvider);
|
||||
if (!taskToCreate) {
|
||||
reject('Unexpected: Task does not exist.');
|
||||
} else {
|
||||
resolve(new TaskExecutionImpl(this, execution.id, taskToCreate));
|
||||
}
|
||||
});
|
||||
|
||||
this._taskExecutionPromises.set(execution.id, createdResult);
|
||||
return createdResult.then(result => {
|
||||
this._taskExecutions.set(execution.id, result);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
protected checkDeprecation(task: vscode.Task, handler: HandlerData) {
|
||||
|
||||
@@ -152,7 +152,8 @@ export class ExtHostTimeline implements IExtHostTimeline {
|
||||
command: item.command ? commandConverter.toInternal(item.command, disposables) : undefined,
|
||||
icon: icon,
|
||||
iconDark: iconDark,
|
||||
themeIcon: themeIcon
|
||||
themeIcon: themeIcon,
|
||||
accessibilityInformation: item.accessibilityInformation
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -188,4 +189,3 @@ export class ExtHostTimeline implements IExtHostTimeline {
|
||||
function getUriKey(uri: URI | undefined): string | undefined {
|
||||
return uri?.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -498,7 +498,7 @@ export class ExtHostTreeView<T> extends Disposable {
|
||||
return node;
|
||||
}
|
||||
|
||||
protected createTreeNode(element: T, extensionTreeItem: azdata.TreeItem, parent: TreeNode | Root): TreeNode { // {{SQL CARBON EDIT}} change to protected, change to azdata.TreeItem
|
||||
protected createTreeNode(element: T, extensionTreeItem: azdata.TreeItem2, parent: TreeNode | Root): TreeNode { // {{SQL CARBON EDIT}} change to protected, change to azdata.TreeItem
|
||||
const disposable = new DisposableStore();
|
||||
const handle = this.createHandle(element, extensionTreeItem, parent);
|
||||
const icon = this.getLightIconPath(extensionTreeItem);
|
||||
@@ -515,10 +515,10 @@ export class ExtHostTreeView<T> extends Disposable {
|
||||
iconDark: this.getDarkIconPath(extensionTreeItem) || icon,
|
||||
themeIcon: extensionTreeItem.iconPath instanceof ThemeIcon ? { id: extensionTreeItem.iconPath.id } : undefined,
|
||||
collapsibleState: isUndefinedOrNull(extensionTreeItem.collapsibleState) ? TreeItemCollapsibleState.None : extensionTreeItem.collapsibleState,
|
||||
// {{SQL CARBON EDIT}}
|
||||
payload: extensionTreeItem.payload,
|
||||
childProvider: extensionTreeItem.childProvider,
|
||||
type: extensionTreeItem.type
|
||||
accessibilityInformation: extensionTreeItem.accessibilityInformation,
|
||||
payload: extensionTreeItem.payload, // {{SQL CARBON EDIT}}
|
||||
childProvider: extensionTreeItem.childProvider, // {{SQL CARBON EDIT}}
|
||||
type: extensionTreeItem.type // {{SQL CARBON EDIT}}
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@@ -95,11 +95,22 @@ export namespace Range {
|
||||
}
|
||||
}
|
||||
|
||||
export namespace TokenType {
|
||||
export function to(type: modes.StandardTokenType): types.StandardTokenType {
|
||||
switch (type) {
|
||||
case modes.StandardTokenType.Comment: return types.StandardTokenType.Comment;
|
||||
case modes.StandardTokenType.Other: return types.StandardTokenType.Other;
|
||||
case modes.StandardTokenType.RegEx: return types.StandardTokenType.RegEx;
|
||||
case modes.StandardTokenType.String: return types.StandardTokenType.String;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Position {
|
||||
export function to(position: IPosition): types.Position {
|
||||
return new types.Position(position.lineNumber - 1, position.column - 1);
|
||||
}
|
||||
export function from(position: types.Position): IPosition {
|
||||
export function from(position: types.Position | vscode.Position): IPosition {
|
||||
return { lineNumber: position.line + 1, column: position.character + 1 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2766,3 +2766,17 @@ export enum ExtensionMode {
|
||||
}
|
||||
|
||||
//#endregion ExtensionContext
|
||||
|
||||
|
||||
//#region Authentication
|
||||
export class AuthenticationSession implements vscode.AuthenticationSession2 {
|
||||
constructor(public id: string, public accessToken: string, public account: { displayName: string, id: string }, public scopes: string[]) { }
|
||||
}
|
||||
|
||||
//#endregion Authentication
|
||||
export enum StandardTokenType {
|
||||
Other = 0,
|
||||
Comment = 1,
|
||||
String = 2,
|
||||
RegEx = 4
|
||||
}
|
||||
|
||||
@@ -573,7 +573,7 @@ export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
|
||||
}
|
||||
const { serializer, extension } = entry;
|
||||
|
||||
const webview = new ExtHostWebview(webviewHandle, this._proxy, options, this.initData, this.workspace, extension, this._deprecationService);
|
||||
const webview = new ExtHostWebview(webviewHandle, this._proxy, reviveOptions(options), this.initData, this.workspace, extension, this._deprecationService);
|
||||
const revivedPanel = new ExtHostWebviewEditor(webviewHandle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
|
||||
this._webviewPanels.set(webviewHandle, revivedPanel);
|
||||
await serializer.deserializeWebviewPanel(revivedPanel, state);
|
||||
@@ -628,7 +628,7 @@ export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
|
||||
throw new Error(`No provider found for '${viewType}'`);
|
||||
}
|
||||
|
||||
const webview = new ExtHostWebview(handle, this._proxy, options, this.initData, this.workspace, entry.extension, this._deprecationService);
|
||||
const webview = new ExtHostWebview(handle, this._proxy, reviveOptions(options), this.initData, this.workspace, entry.extension, this._deprecationService);
|
||||
const revivedPanel = new ExtHostWebviewEditor(handle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
|
||||
this._webviewPanels.set(handle, revivedPanel);
|
||||
|
||||
@@ -761,6 +761,15 @@ function convertWebviewOptions(
|
||||
};
|
||||
}
|
||||
|
||||
function reviveOptions(
|
||||
options: modes.IWebviewOptions & modes.IWebviewPanelOptions
|
||||
): vscode.WebviewOptions {
|
||||
return {
|
||||
...options,
|
||||
localResourceRoots: options.localResourceRoots?.map(components => URI.from(components)),
|
||||
};
|
||||
}
|
||||
|
||||
function getDefaultLocalResourceRoots(
|
||||
extension: IExtensionDescription,
|
||||
workspace: IExtHostWorkspace | undefined,
|
||||
|
||||
Reference in New Issue
Block a user