Merge from vscode 7eaf220cafb9d9e901370ffce02229171cbf3ea6

This commit is contained in:
ADS Merger
2020-09-03 02:34:56 +00:00
committed by Anthony Dresser
parent 39d9eed585
commit a63578e6f7
519 changed files with 14338 additions and 6670 deletions

View File

@@ -16,6 +16,7 @@ import { IWorkspacesService, hasWorkspaceFileExtension, IRecent } from 'vs/platf
import { Schemas } from 'vs/base/common/network';
import { ILogService } from 'vs/platform/log/common/log';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IViewDescriptorService, IViewsService } from 'vs/workbench/common/views';
// -----------------------------------------------------------------
// The following commands are registered on both sides separately.
@@ -264,3 +265,42 @@ CommandsRegistry.registerCommand('_extensionTests.getLogLevel', function (access
return logService.getLevel();
});
CommandsRegistry.registerCommand('_workbench.action.moveViews', async function (accessor: ServicesAccessor, options: { viewIds: string[], destinationId: string }) {
const viewDescriptorService = accessor.get(IViewDescriptorService);
const destination = viewDescriptorService.getViewContainerById(options.destinationId);
if (!destination) {
return;
}
// FYI, don't use `moveViewsToContainer` in 1 shot, because it expects all views to have the same current location
for (const viewId of options.viewIds) {
const viewDescriptor = viewDescriptorService.getViewDescriptorById(viewId);
if (viewDescriptor?.canMoveView) {
viewDescriptorService.moveViewsToContainer([viewDescriptor], destination);
}
}
await accessor.get(IViewsService).openViewContainer(destination.id, true);
});
export class MoveViewsAPICommand {
public static readonly ID = 'vscode.moveViews';
public static execute(executor: ICommandsExecutor, options: { viewIds: string[], destinationId: string }): Promise<any> {
if (!Array.isArray(options?.viewIds) || typeof options?.destinationId !== 'string') {
return Promise.reject('Invalid arguments');
}
return executor.executeCommand('_workbench.action.moveViews', options);
}
}
CommandsRegistry.registerCommand({
id: MoveViewsAPICommand.ID,
handler: adjustHandler(MoveViewsAPICommand.execute),
description: {
description: 'Move Views',
args: []
}
});

View File

@@ -79,7 +79,7 @@ import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePa
import { IExtHostConsumerFileSystem } from 'vs/workbench/api/common/extHostFileSystemConsumer';
import { ExtHostWebviewViews } from 'vs/workbench/api/common/extHostWebviewView';
import { ExtHostCustomEditors } from 'vs/workbench/api/common/extHostCustomEditors';
import { ExtHostWebviewSerializer } from 'vs/workbench/api/common/extHostWebviewSerializer';
import { ExtHostWebviewPanels } from 'vs/workbench/api/common/extHostWebviewPanels';
export interface IExtensionApiFactory {
(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode;
@@ -129,7 +129,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const extHostDocuments = rpcProtocol.set(ExtHostContext.ExtHostDocuments, new ExtHostDocuments(rpcProtocol, extHostDocumentsAndEditors));
const extHostDocumentContentProviders = rpcProtocol.set(ExtHostContext.ExtHostDocumentContentProviders, new ExtHostDocumentContentProvider(rpcProtocol, extHostDocumentsAndEditors, extHostLogService));
const extHostDocumentSaveParticipant = rpcProtocol.set(ExtHostContext.ExtHostDocumentSaveParticipant, new ExtHostDocumentSaveParticipant(extHostLogService, extHostDocuments, rpcProtocol.getProxy(MainContext.MainThreadTextEditors)));
const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors));
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors, initData.environment, extHostLogService, extensionStoragePaths));
const extHostEditors = rpcProtocol.set(ExtHostContext.ExtHostEditors, new ExtHostEditors(rpcProtocol, extHostDocumentsAndEditors, extHostNotebook));
const extHostTreeViews = rpcProtocol.set(ExtHostContext.ExtHostTreeViews, new ExtHostTreeViews(rpcProtocol.getProxy(MainContext.MainThreadTreeViews), extHostCommands, extHostLogService));
const extHostEditorInsets = rpcProtocol.set(ExtHostContext.ExtHostEditorInsets, new ExtHostEditorInsets(rpcProtocol.getProxy(MainContext.MainThreadEditorInsets), extHostEditors, initData.environment));
const extHostDiagnostics = rpcProtocol.set(ExtHostContext.ExtHostDiagnostics, new ExtHostDiagnostics(rpcProtocol, extHostLogService));
@@ -141,13 +142,12 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments));
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, initData.environment, extHostLogService, extensionStoragePaths));
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));
const extHostWebviews = rpcProtocol.set(ExtHostContext.ExtHostWebviews, new ExtHostWebviews(rpcProtocol, initData.environment, extHostWorkspace, extHostLogService, extHostApiDeprecation));
const extHostWebviewSerializers = rpcProtocol.set(ExtHostContext.ExtHostWebviewSerializer, new ExtHostWebviewSerializer(rpcProtocol, extHostWebviews));
const extHostCustomEditors = rpcProtocol.set(ExtHostContext.ExtHostCustomEditors, new ExtHostCustomEditors(rpcProtocol, extHostDocuments, extensionStoragePaths, extHostWebviews));
const extHostWebviewPanels = rpcProtocol.set(ExtHostContext.ExtHostWebviewPanels, new ExtHostWebviewPanels(rpcProtocol, extHostWebviews, extHostWorkspace));
const extHostCustomEditors = rpcProtocol.set(ExtHostContext.ExtHostCustomEditors, new ExtHostCustomEditors(rpcProtocol, extHostDocuments, extensionStoragePaths, extHostWebviews, extHostWebviewPanels));
const extHostWebviewViews = rpcProtocol.set(ExtHostContext.ExtHostWebviewViews, new ExtHostWebviewViews(rpcProtocol, extHostWebviews));
// Check that no named customers are missing
@@ -573,7 +573,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostOutputService.createOutputChannel(name);
},
createWebviewPanel(viewType: string, title: string, showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean }, options?: vscode.WebviewPanelOptions & vscode.WebviewOptions): vscode.WebviewPanel {
return extHostWebviews.createWebviewPanel(extension, viewType, title, showOptions, options);
return extHostWebviewPanels.createWebviewPanel(extension, viewType, title, showOptions, options);
},
createWebviewTextEditorInset(editor: vscode.TextEditor, line: number, height: number, options?: vscode.WebviewOptions): vscode.WebviewEditorInset {
checkProposedApiEnabled(extension);
@@ -598,7 +598,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
return extHostTreeViews.createTreeView(viewId, options, extension);
},
registerWebviewPanelSerializer: (viewType: string, serializer: vscode.WebviewPanelSerializer) => {
return extHostWebviewSerializers.registerWebviewPanelSerializer(extension, viewType, serializer);
return extHostWebviewPanels.registerWebviewPanelSerializer(extension, viewType, serializer);
},
registerCustomEditorProvider: (viewType: string, provider: vscode.CustomTextEditorProvider | vscode.CustomReadonlyEditorProvider, options: { webviewOptions?: vscode.WebviewPanelOptions, supportsMultipleEditorsPerDocument?: boolean } = {}) => {
return extHostCustomEditors.registerCustomEditorProvider(extension, viewType, provider, options);
@@ -958,7 +958,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
},
get notebookDocuments(): vscode.NotebookDocument[] {
checkProposedApiEnabled(extension);
return extHostNotebook.notebookDocuments;
return extHostNotebook.notebookDocuments.map(d => d.notebookDocument);
},
get visibleNotebookEditors() {
checkProposedApiEnabled(extension);
@@ -972,13 +972,12 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
checkProposedApiEnabled(extension);
return extHostNotebook.onDidChangeActiveNotebookKernel;
},
registerNotebookContentProvider: (viewType: string, provider: vscode.NotebookContentProvider) => {
registerNotebookContentProvider: (viewType: string, provider: vscode.NotebookContentProvider, options?: {
transientOutputs: boolean;
transientMetadata: { [K in keyof vscode.NotebookCellMetadata]?: boolean }
}) => {
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);
return extHostNotebook.registerNotebookContentProvider(extension, viewType, provider, options);
},
registerNotebookKernelProvider: (selector: vscode.NotebookDocumentFilter, provider: vscode.NotebookKernelProvider) => {
checkProposedApiEnabled(extension);
@@ -996,6 +995,14 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
checkProposedApiEnabled(extension);
return extHostNotebook.onDidChangeNotebookCells(listener, thisArgs, disposables);
},
onDidChangeNotebookEditorSelection(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
return extHostNotebook.onDidChangeNotebookEditorSelection(listener, thisArgs, disposables);
},
onDidChangeNotebookEditorVisibleRanges(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
return extHostNotebook.onDidChangeNotebookEditorVisibleRanges(listener, thisArgs, disposables);
},
onDidChangeCellOutputs(listener, thisArgs?, disposables?) {
checkProposedApiEnabled(extension);
return extHostNotebook.onDidChangeCellOutputs(listener, thisArgs, disposables);
@@ -1011,6 +1018,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
createConcatTextDocument(notebook, selector) {
checkProposedApiEnabled(extension);
return new ExtHostNotebookConcatDocument(extHostNotebook, extHostDocuments, notebook, selector);
},
createCellStatusBarItem(cell: vscode.NotebookCell, alignment?: vscode.NotebookCellStatusBarAlignment, priority?: number): vscode.NotebookCellStatusBarItem {
checkProposedApiEnabled(extension);
return extHostNotebook.createNotebookCellStatusBarItemInternal(cell, alignment, priority);
}
};
@@ -1114,7 +1125,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
SymbolKind: extHostTypes.SymbolKind,
SymbolTag: extHostTypes.SymbolTag,
Task: extHostTypes.Task,
Task2: extHostTypes.Task,
TaskGroup: extHostTypes.TaskGroup,
TaskPanelKind: extHostTypes.TaskPanelKind,
TaskRevealKind: extHostTypes.TaskRevealKind,
@@ -1146,7 +1156,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
CellKind: extHostTypes.CellKind,
CellOutputKind: extHostTypes.CellOutputKind,
NotebookCellRunState: extHostTypes.NotebookCellRunState,
NotebookRunState: extHostTypes.NotebookRunState
NotebookRunState: extHostTypes.NotebookRunState,
NotebookCellStatusBarAlignment: extHostTypes.NotebookCellStatusBarAlignment,
NotebookEditorRevealType: extHostTypes.NotebookEditorRevealType
};
};
}

View File

@@ -42,7 +42,7 @@ import { IRevealOptions, ITreeItem } from 'vs/workbench/common/views';
import { IAdapterDescriptor, IConfig, IDebugSessionReplMode } from 'vs/workbench/contrib/debug/common/debug';
import { ITextQueryBuilderOptions } from 'vs/workbench/contrib/search/common/queryBuilder';
import { ITerminalDimensions, IShellLaunchConfig, ITerminalLaunchError } from 'vs/workbench/contrib/terminal/common/terminal';
import { ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions';
import { ActivationKind, ExtensionActivationError } from 'vs/workbench/services/extensions/common/extensions';
import { createExtHostContextProxyIdentifier as createExtId, createMainContextProxyIdentifier as createMainId, IRPCProtocol } from 'vs/workbench/services/extensions/common/proxyIdentifier';
import * as search from 'vs/workbench/services/search/common/search';
import { SaveReason } from 'vs/workbench/common/editor';
@@ -51,7 +51,7 @@ import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
import { TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor, InternalTimelineOptions } from 'vs/workbench/contrib/timeline/common/timeline';
import { revive } from 'vs/base/common/marshalling';
import { IProcessedOutput, INotebookDisplayOrder, NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEvent, NotebookDataDto, INotebookKernelInfoDto, IMainCellDto, INotebookDocumentFilter, INotebookKernelInfoDto2 } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { IProcessedOutput, INotebookDisplayOrder, NotebookCellMetadata, NotebookDocumentMetadata, ICellEditOperation, NotebookCellsChangedEvent, NotebookDataDto, IMainCellDto, INotebookDocumentFilter, INotebookKernelInfoDto2, TransientMetadata, INotebookCellStatusBarEntry, ICellRange } 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';
@@ -454,6 +454,7 @@ export interface MainThreadTerminalServiceShape extends IDisposable {
$stopSendingDataEvents(): void;
$startLinkProvider(): void;
$stopLinkProvider(): void;
$registerProcessSupport(isSupported: boolean): void;
$setEnvironmentVariableCollection(extensionIdentifier: string, persistent: boolean, collection: ISerializableEnvironmentVariableCollection | undefined): void;
// Process
@@ -585,7 +586,7 @@ export interface ExtHostEditorInsetsShape {
$onDidReceiveMessage(handle: number, message: any): void;
}
export type WebviewPanelHandle = string;
export type WebviewHandle = string;
export interface WebviewPanelShowOptions {
readonly viewColumn?: EditorViewColumn;
@@ -613,31 +614,36 @@ export interface CustomTextEditorCapabilities {
}
export interface MainThreadWebviewsShape extends IDisposable {
$createWebviewPanel(extension: WebviewExtensionDescription, handle: WebviewPanelHandle, viewType: string, title: string, showOptions: WebviewPanelShowOptions, options: modes.IWebviewPanelOptions & modes.IWebviewOptions): void;
$disposeWebview(handle: WebviewPanelHandle): void;
$reveal(handle: WebviewPanelHandle, showOptions: WebviewPanelShowOptions): void;
$setTitle(handle: WebviewPanelHandle, value: string): void;
$setIconPath(handle: WebviewPanelHandle, value: { light: UriComponents, dark: UriComponents; } | undefined): void;
$setHtml(handle: WebviewHandle, value: string): void;
$setOptions(handle: WebviewHandle, options: modes.IWebviewOptions): void;
$postMessage(handle: WebviewHandle, value: any): Promise<boolean>
}
$setHtml(handle: WebviewPanelHandle, value: string): void;
$setOptions(handle: WebviewPanelHandle, options: modes.IWebviewOptions): void;
$postMessage(handle: WebviewPanelHandle, value: any): Promise<boolean>;
export interface MainThreadWebviewPanelsShape extends IDisposable {
$createWebviewPanel(extension: WebviewExtensionDescription, handle: WebviewHandle, viewType: string, title: string, showOptions: WebviewPanelShowOptions, options: modes.IWebviewPanelOptions & modes.IWebviewOptions): void;
$disposeWebview(handle: WebviewHandle): void;
$reveal(handle: WebviewHandle, showOptions: WebviewPanelShowOptions): void;
$setTitle(handle: WebviewHandle, value: string): void;
$setIconPath(handle: WebviewHandle, value: { light: UriComponents, dark: UriComponents; } | undefined): void;
$registerSerializer(viewType: string): void;
$unregisterSerializer(viewType: string): void;
}
export interface MainThreadCustomEditorsShape extends IDisposable {
$registerTextEditorProvider(extension: WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions, capabilities: CustomTextEditorCapabilities): void;
$registerCustomEditorProvider(extension: WebviewExtensionDescription, viewType: string, options: modes.IWebviewPanelOptions, supportsMultipleEditorsPerDocument: boolean): void;
$unregisterEditorProvider(viewType: string): void;
$onDidEdit(resource: UriComponents, viewType: string, editId: number, label: string | undefined): void;
$onContentChange(resource: UriComponents, viewType: string): void;
}
export interface MainThreadWebviewViewsShape extends IDisposable {
$registerWebviewViewProvider(viewType: string, options?: { retainContextWhenHidden?: boolean }): void;
$unregisterWebviewViewProvider(viewType: string): void;
$setWebviewViewTitle(handle: WebviewPanelHandle, value: string | undefined): void;
$setWebviewViewTitle(handle: WebviewHandle, value: string | undefined): void;
}
export interface WebviewPanelViewStateData {
@@ -649,18 +655,18 @@ export interface WebviewPanelViewStateData {
}
export interface ExtHostWebviewsShape {
$onMessage(handle: WebviewPanelHandle, message: any): void;
$onMissingCsp(handle: WebviewPanelHandle, extensionId: string): void;
$onDidChangeWebviewPanelViewStates(newState: WebviewPanelViewStateData): void;
$onDidDisposeWebviewPanel(handle: WebviewPanelHandle): Promise<void>;
$onMessage(handle: WebviewHandle, message: any): void;
$onMissingCsp(handle: WebviewHandle, extensionId: string): void;
}
export interface ExtHostWebviewSerializerShape {
$deserializeWebviewPanel(newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
export interface ExtHostWebviewPanelsShape {
$onDidChangeWebviewPanelViewStates(newState: WebviewPanelViewStateData): void;
$onDidDisposeWebviewPanel(handle: WebviewHandle): Promise<void>;
$deserializeWebviewPanel(newWebviewHandle: WebviewHandle, viewType: string, title: string, state: any, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions): Promise<void>;
}
export interface ExtHostCustomEditorsShape {
$resolveWebviewEditor(resource: UriComponents, newWebviewHandle: WebviewPanelHandle, viewType: string, title: string, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions, cancellation: CancellationToken): Promise<void>;
$resolveWebviewEditor(resource: UriComponents, newWebviewHandle: WebviewHandle, viewType: string, title: string, position: EditorViewColumn, options: modes.IWebviewOptions & modes.IWebviewPanelOptions, cancellation: CancellationToken): Promise<void>;
$createCustomDocument(resource: UriComponents, viewType: string, backupId: string | undefined, cancellation: CancellationToken): Promise<{ editable: boolean }>;
$disposeCustomDocument(resource: UriComponents, viewType: string): Promise<void>;
@@ -674,15 +680,15 @@ export interface ExtHostCustomEditorsShape {
$backup(resource: UriComponents, viewType: string, cancellation: CancellationToken): Promise<string>;
$onMoveCustomEditor(handle: WebviewPanelHandle, newResource: UriComponents, viewType: string): Promise<void>;
$onMoveCustomEditor(handle: WebviewHandle, newResource: UriComponents, viewType: string): Promise<void>;
}
export interface ExtHostWebviewViewsShape {
$resolveWebviewView(webviewHandle: WebviewPanelHandle, viewType: string, state: any, cancellation: CancellationToken): Promise<void>;
$resolveWebviewView(webviewHandle: WebviewHandle, viewType: string, state: any, cancellation: CancellationToken): Promise<void>;
$onDidChangeWebviewViewVisibility(webviewHandle: WebviewPanelHandle, visible: boolean): void;
$onDidChangeWebviewViewVisibility(webviewHandle: WebviewHandle, visible: boolean): void;
$disposeWebviewView(webviewHandle: WebviewPanelHandle): void;
$disposeWebviewView(webviewHandle: WebviewHandle): void;
}
export enum CellKind {
@@ -718,22 +724,29 @@ export type NotebookCellOutputsSplice = [
IProcessedOutput[]
];
export enum NotebookEditorRevealType {
Default = 0,
InCenter = 1,
InCenterIfOutsideViewport = 2,
}
export type INotebookCellStatusBarEntryDto = Dto<INotebookCellStatusBarEntry>;
export interface MainThreadNotebookShape extends IDisposable {
$registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string, supportBackup: boolean, kernelInfoDto: INotebookKernelInfoDto | undefined): Promise<void>;
$registerNotebookProvider(extension: NotebookExtensionDescription, viewType: string, supportBackup: boolean, options: { transientOutputs: boolean; transientMetadata: TransientMetadata }): Promise<void>;
$onNotebookChange(viewType: string, resource: UriComponents): Promise<void>;
$unregisterNotebookProvider(viewType: string): Promise<void>;
$registerNotebookKernel(extension: NotebookExtensionDescription, id: string, label: string, selectors: (string | IRelativePattern)[], preloads: UriComponents[]): Promise<void>;
$registerNotebookKernelProvider(extension: NotebookExtensionDescription, handle: number, documentFilter: INotebookDocumentFilter): Promise<void>;
$unregisterNotebookKernelProvider(handle: number): Promise<void>;
$onNotebookKernelChange(handle: number): void;
$unregisterNotebookKernel(id: string): Promise<void>;
$tryApplyEdits(viewType: string, resource: UriComponents, modelVersionId: number, edits: ICellEditOperation[], renderers: number[]): Promise<boolean>;
$onNotebookKernelChange(handle: number, uri: UriComponents | undefined): void;
$tryApplyEdits(viewType: string, resource: UriComponents, modelVersionId: number, edits: ICellEditOperation[]): Promise<boolean>;
$updateNotebookLanguages(viewType: string, resource: UriComponents, languages: string[]): Promise<void>;
$updateNotebookMetadata(viewType: string, resource: UriComponents, metadata: NotebookDocumentMetadata): Promise<void>;
$updateNotebookCellMetadata(viewType: string, resource: UriComponents, handle: number, metadata: NotebookCellMetadata | undefined): Promise<void>;
$spliceNotebookCellOutputs(viewType: string, resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[]): Promise<void>;
$postMessage(editorId: string, forRendererId: string | undefined, value: any): Promise<boolean>;
$setStatusBarEntry(id: number, statusBarEntry: INotebookCellStatusBarEntryDto): Promise<void>;
$tryRevealRange(id: string, range: ICellRange, revealType: NotebookEditorRevealType): Promise<void>;
$onDidEdit(resource: UriComponents, viewType: string, editId: number, label: string | undefined): void;
$onContentChange(resource: UriComponents, viewType: string): void;
}
@@ -1052,6 +1065,7 @@ export interface ExtHostAuthenticationShape {
$logout(id: string, sessionId: string): Promise<void>;
$onDidChangeAuthenticationSessions(id: string, label: string, event: modes.AuthenticationSessionsChangeEvent): Promise<void>;
$onDidChangeAuthenticationProviders(added: modes.AuthenticationProviderInformation[], removed: modes.AuthenticationProviderInformation[]): Promise<void>;
$setProviders(providers: modes.AuthenticationProviderInformation[]): Promise<void>;
}
export interface ExtHostSearchShape {
@@ -1079,7 +1093,7 @@ export type IResolveAuthorityResult = IResolveAuthorityErrorResult | IResolveAut
export interface ExtHostExtensionServiceShape {
$resolveAuthority(remoteAuthority: string, resolveAttempt: number): Promise<IResolveAuthorityResult>;
$startExtensionHost(enabledExtensionIds: ExtensionIdentifier[]): Promise<void>;
$activateByEvent(activationEvent: string): Promise<void>;
$activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise<void>;
$activate(extensionId: ExtensionIdentifier, reason: ExtensionActivationReason): Promise<boolean>;
$setRemoteEnvironment(env: { [key: string]: string | null; }): Promise<void>;
$updateRemoteConnectionData(connectionData: IRemoteConnectionData): Promise<void>;
@@ -1237,7 +1251,14 @@ export interface IWorkspaceEditEntryMetadataDto {
iconPath?: { id: string } | UriComponents | { light: UriComponents, dark: UriComponents };
}
export const enum WorkspaceEditType {
File = 1,
Text = 2,
Cell = 3,
}
export interface IWorkspaceFileEditDto {
_type: WorkspaceEditType.File;
oldUri?: UriComponents;
newUri?: UriComponents;
options?: modes.WorkspaceFileEditOptions
@@ -1245,14 +1266,23 @@ export interface IWorkspaceFileEditDto {
}
export interface IWorkspaceTextEditDto {
_type: WorkspaceEditType.Text;
resource: UriComponents;
edit: modes.TextEdit;
modelVersionId?: number;
metadata?: IWorkspaceEditEntryMetadataDto;
}
export interface IWorkspaceCellEditDto {
_type: WorkspaceEditType.Cell;
resource: UriComponents;
edit: ICellEditOperation;
modelVersionId?: number;
metadata?: IWorkspaceEditEntryMetadataDto;
}
export interface IWorkspaceEditDto {
edits: Array<IWorkspaceFileEditDto | IWorkspaceTextEditDto>;
edits: Array<IWorkspaceFileEditDto | IWorkspaceTextEditDto | IWorkspaceCellEditDto>;
// todo@joh reject should go into rename
rejectReason?: string;
@@ -1602,9 +1632,22 @@ export interface INotebookSelectionChangeEvent {
selections: number[];
}
export interface INotebookCellVisibleRange {
start: number;
end: number;
}
export interface INotebookVisibleRangesEvent {
ranges: INotebookCellVisibleRange[];
}
export interface INotebookEditorPropertiesChangeData {
selections: INotebookSelectionChangeEvent | null;
visibleRanges: INotebookVisibleRangesEvent | null;
}
export interface INotebookDocumentPropertiesChangeData {
metadata: NotebookDocumentMetadata | null;
selections: INotebookSelectionChangeEvent | null;
}
export interface INotebookModelAddedData {
@@ -1614,13 +1657,14 @@ export interface INotebookModelAddedData {
cells: IMainCellDto[],
viewType: string;
metadata?: NotebookDocumentMetadata;
attachedEditor?: { id: string; selections: number[]; }
attachedEditor?: { id: string; selections: number[]; visibleRanges: ICellRange[] }
}
export interface INotebookEditorAddData {
id: string;
documentUri: UriComponents;
selections: number[];
visibleRanges: ICellRange[];
}
export interface INotebookDocumentsAndEditorsDelta {
@@ -1637,8 +1681,6 @@ export interface ExtHostNotebookShape {
$resolveNotebookEditor(viewType: string, uri: UriComponents, editorId: string): Promise<void>;
$provideNotebookKernels(handle: number, uri: UriComponents, token: CancellationToken): Promise<INotebookKernelInfoDto2[]>;
$resolveNotebookKernel(handle: number, editorId: string, uri: UriComponents, kernelId: string, token: CancellationToken): Promise<void>;
$executeNotebookByAttachedKernel(viewType: string, uri: UriComponents, cellHandle: number | undefined): Promise<void>;
$cancelNotebookByAttachedKernel(viewType: string, uri: UriComponents, cellHandle: number | undefined): Promise<void>;
$executeNotebookKernelFromProvider(handle: number, uri: UriComponents, kernelId: string, cellHandle: number | undefined): Promise<void>;
$cancelNotebookKernelFromProvider(handle: number, uri: UriComponents, kernelId: string, cellHandle: number | undefined): Promise<void>;
$executeNotebook2(kernelId: string, viewType: string, uri: UriComponents, cellHandle: number | undefined): Promise<void>;
@@ -1648,9 +1690,10 @@ export interface ExtHostNotebookShape {
$acceptDisplayOrder(displayOrder: INotebookDisplayOrder): void;
$acceptNotebookActiveKernelChange(event: { uri: UriComponents, providerHandle: number | undefined, kernelId: string | undefined }): void;
$onDidReceiveMessage(editorId: string, rendererId: string | undefined, message: unknown): void;
$acceptModelChanged(uriComponents: UriComponents, event: NotebookCellsChangedEvent): void;
$acceptModelChanged(uriComponents: UriComponents, event: NotebookCellsChangedEvent, isDirty: boolean): void;
$acceptModelSaved(uriComponents: UriComponents): void;
$acceptEditorPropertiesChanged(uriComponents: UriComponents, data: INotebookEditorPropertiesChangeData): void;
$acceptEditorPropertiesChanged(id: string, data: INotebookEditorPropertiesChangeData): void;
$acceptDocumentPropertiesChanged(uriComponents: UriComponents, data: INotebookDocumentPropertiesChangeData): void;
$acceptDocumentAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta): void;
$undoNotebook(viewType: string, uri: UriComponents, editId: number, isDirty: boolean): Promise<void>;
$redoNotebook(viewType: string, uri: UriComponents, editId: number, isDirty: boolean): Promise<void>;
@@ -1713,6 +1756,9 @@ export const MainContext = {
MainThreadTelemetry: createMainId<MainThreadTelemetryShape>('MainThreadTelemetry'),
MainThreadTerminalService: createMainId<MainThreadTerminalServiceShape>('MainThreadTerminalService'),
MainThreadWebviews: createMainId<MainThreadWebviewsShape>('MainThreadWebviews'),
MainThreadWebviewPanels: createMainId<MainThreadWebviewPanelsShape>('MainThreadWebviewPanels'),
MainThreadWebviewViews: createMainId<MainThreadWebviewViewsShape>('MainThreadWebviewViews'),
MainThreadCustomEditors: createMainId<MainThreadCustomEditorsShape>('MainThreadCustomEditors'),
MainThreadUrls: createMainId<MainThreadUrlsShape>('MainThreadUrls'),
MainThreadWorkspace: createMainId<MainThreadWorkspaceShape>('MainThreadWorkspace'),
MainThreadFileSystem: createMainId<MainThreadFileSystemShape>('MainThreadFileSystem'),
@@ -1753,7 +1799,7 @@ export const ExtHostContext = {
ExtHostWorkspace: createExtId<ExtHostWorkspaceShape>('ExtHostWorkspace'),
ExtHostWindow: createExtId<ExtHostWindowShape>('ExtHostWindow'),
ExtHostWebviews: createExtId<ExtHostWebviewsShape>('ExtHostWebviews'),
ExtHostWebviewSerializer: createExtId<ExtHostWebviewSerializerShape>('ExtHostWebviewSerializer'),
ExtHostWebviewPanels: createExtId<ExtHostWebviewPanelsShape>('ExtHostWebviewPanels'),
ExtHostCustomEditors: createExtId<ExtHostCustomEditorsShape>('ExtHostCustomEditors'),
ExtHostWebviewViews: createExtId<ExtHostWebviewViewsShape>('ExtHostWebviewViews'),
ExtHostEditorInsets: createExtId<ExtHostEditorInsetsShape>('ExtHostEditorInsets'),

View File

@@ -28,6 +28,11 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
this._proxy = mainContext.getProxy(MainContext.MainThreadAuthentication);
}
$setProviders(providers: vscode.AuthenticationProviderInformation[]): Promise<void> {
this._providers = providers;
return Promise.resolve();
}
getProviderIds(): Promise<ReadonlyArray<string>> {
return this._proxy.$getProviderIds();
}
@@ -182,9 +187,9 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
}
$onDidChangeAuthenticationProviders(added: modes.AuthenticationProviderInformation[], removed: modes.AuthenticationProviderInformation[]) {
added.forEach(id => {
if (!this._providers.includes(id)) {
this._providers.push(id);
added.forEach(provider => {
if (!this._providers.some(p => p.id === provider.id)) {
this._providers.push(provider);
}
});

View File

@@ -141,7 +141,7 @@ export class ExtHostCommands implements ExtHostCommandsShape {
try {
const result = await this._proxy.$executeCommand<T>(id, toArgs, retry);
return revive(result);
return revive<any>(result);
} catch (e) {
// Rerun the command when it wasn't known, had arguments, and when retry
// is enabled. We do this because the command might be registered inside

View File

@@ -14,6 +14,7 @@ import { IExtensionDescription } from 'vs/platform/extensions/common/extensions'
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
import { ExtHostWebviews, toExtensionData } from 'vs/workbench/api/common/extHostWebview';
import { ExtHostWebviewPanels } from 'vs/workbench/api/common/extHostWebviewPanels';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import type * as vscode from 'vscode';
import { Cache } from './cache';
@@ -154,7 +155,7 @@ class EditorProviderStore {
export class ExtHostCustomEditors implements extHostProtocol.ExtHostCustomEditorsShape {
private readonly _proxy: extHostProtocol.MainThreadWebviewsShape;
private readonly _proxy: extHostProtocol.MainThreadCustomEditorsShape;
private readonly _editorProviders = new EditorProviderStore();
@@ -165,8 +166,9 @@ export class ExtHostCustomEditors implements extHostProtocol.ExtHostCustomEditor
private readonly _extHostDocuments: ExtHostDocuments,
private readonly _extensionStoragePaths: IExtensionStoragePaths | undefined,
private readonly _extHostWebview: ExtHostWebviews,
private readonly _extHostWebviewPanels: ExtHostWebviewPanels,
) {
this._proxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadWebviews);
this._proxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadCustomEditors);
}
public registerCustomEditorProvider(
@@ -247,7 +249,7 @@ export class ExtHostCustomEditors implements extHostProtocol.ExtHostCustomEditor
async $resolveWebviewEditor(
resource: UriComponents,
handle: extHostProtocol.WebviewPanelHandle,
handle: extHostProtocol.WebviewHandle,
viewType: string,
title: string,
position: EditorViewColumn,
@@ -260,7 +262,7 @@ export class ExtHostCustomEditors implements extHostProtocol.ExtHostCustomEditor
}
const webview = this._extHostWebview.createNewWebview(handle, options, entry.extension);
const panel = this._extHostWebview.createNewWebviewPanel(handle, viewType, title, position, options, webview);
const panel = this._extHostWebviewPanels.createNewWebviewPanel(handle, viewType, title, position, options, webview);
const revivedResource = URI.revive(resource);
@@ -297,7 +299,7 @@ export class ExtHostCustomEditors implements extHostProtocol.ExtHostCustomEditor
throw new Error(`Provider does not implement move '${viewType}'`);
}
const webview = this._extHostWebview.getWebviewPanel(handle);
const webview = this._extHostWebviewPanels.getWebviewPanel(handle);
if (!webview) {
throw new Error(`No webview found`);
}

View File

@@ -19,7 +19,7 @@ interface ProviderData {
extensionId: ExtensionIdentifier;
}
export class ExtHostDecorations implements IExtHostDecorations {
export class ExtHostDecorations implements ExtHostDecorationsShape {
private static _handlePool = 0;
@@ -85,4 +85,4 @@ export class ExtHostDecorations implements IExtHostDecorations {
}
export const IExtHostDecorations = createDecorator<IExtHostDecorations>('IExtHostDecorations');
export interface IExtHostDecorations extends ExtHostDecorations, ExtHostDecorationsShape { }
export interface IExtHostDecorations extends ExtHostDecorations { }

View File

@@ -6,7 +6,7 @@
import { Event } from 'vs/base/common/event';
import { URI, UriComponents } from 'vs/base/common/uri';
import { illegalState } from 'vs/base/common/errors';
import { ExtHostDocumentSaveParticipantShape, MainThreadTextEditorsShape, IWorkspaceEditDto } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostDocumentSaveParticipantShape, MainThreadTextEditorsShape, IWorkspaceEditDto, WorkspaceEditType } from 'vs/workbench/api/common/extHost.protocol';
import { TextEdit } from 'vs/workbench/api/common/extHostTypes';
import { Range, TextDocumentSaveReason, EndOfLine } from 'vs/workbench/api/common/extHostTypeConverters';
import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments';
@@ -146,6 +146,7 @@ export class ExtHostDocumentSaveParticipant implements ExtHostDocumentSavePartic
if (Array.isArray(value) && (<vscode.TextEdit[]>value).every(e => e instanceof TextEdit)) {
for (const { newText, newEol, range } of value) {
dto.edits.push({
_type: WorkspaceEditType.Text,
resource: document.uri,
edit: {
range: range && Range.from(range),

View File

@@ -5,7 +5,6 @@
import * as nls from 'vs/nls';
import * as path from 'vs/base/common/path';
import * as platform from 'vs/base/common/platform';
import { originalFSPath, joinPath } from 'vs/base/common/resources';
import { Barrier, timeout } from 'vs/base/common/async';
import { dispose, toDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
@@ -17,7 +16,7 @@ import { ExtHostConfiguration, IExtHostConfiguration } from 'vs/workbench/api/co
import { ActivatedExtension, EmptyExtension, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator';
import { ExtHostStorage, IExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
import { ExtHostWorkspace, IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { ExtensionActivationError, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { ExtensionActivationError, checkProposedApiEnabled, ActivationKind } from 'vs/workbench/services/extensions/common/extensions';
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
import * as errors from 'vs/base/common/errors';
import type * as vscode from 'vscode';
@@ -385,14 +384,7 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
subscriptions: [],
get extensionUri() { return extensionDescription.extensionLocation; },
get extensionPath() { return extensionDescription.extensionLocation.fsPath; },
asAbsolutePath(relativePath: string) {
if (platform.isWeb) {
// web worker
return URI.joinPath(extensionDescription.extensionLocation, relativePath).toString();
} else {
return path.join(extensionDescription.extensionLocation.fsPath, relativePath);
}
},
asAbsolutePath(relativePath: string) { return path.join(extensionDescription.extensionLocation.fsPath, relativePath); },
get storagePath() { return that._storagePath.workspaceValue(extensionDescription)?.fsPath; },
get globalStoragePath() { return that._storagePath.globalValue(extensionDescription).fsPath; },
get logPath() { return path.join(that._initData.logsLocation.fsPath, extensionDescription.identifier.value); },
@@ -686,7 +678,11 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
return this._startExtensionHost();
}
public $activateByEvent(activationEvent: string): Promise<void> {
public $activateByEvent(activationEvent: string, activationKind: ActivationKind): Promise<void> {
if (activationKind === ActivationKind.Immediate) {
return this._activateByEvent(activationEvent, false);
}
return (
this._readyToRunExtensions.wait()
.then(_ => this._activateByEvent(activationEvent, false))

View File

@@ -8,12 +8,11 @@ import { IRelativePattern, parse } from 'vs/base/common/glob';
import { URI } from 'vs/base/common/uri';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import type * as vscode from 'vscode';
import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, MainContext, MainThreadTextEditorsShape, IWorkspaceFileEditDto, IWorkspaceTextEditDto, SourceTargetPair } from './extHost.protocol';
import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, MainContext, MainThreadTextEditorsShape, SourceTargetPair, IWorkspaceEditDto } from './extHost.protocol';
import * as typeConverter from './extHostTypeConverters';
import { Disposable, WorkspaceEdit } from './extHostTypes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { FileOperation } from 'vs/platform/files/common/files';
import { flatten } from 'vs/base/common/arrays';
import { CancellationToken } from 'vs/base/common/cancellation';
import { ILogService } from 'vs/platform/log/common/log';
@@ -217,14 +216,13 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ
}
if (edits.length > 0) {
// flatten all WorkspaceEdits collected via waitUntil-call
// and apply them in one go.
const allEdits = new Array<Array<IWorkspaceFileEditDto | IWorkspaceTextEditDto>>();
// concat all WorkspaceEdits collected via waitUntil-call and apply them in one go.
const dto: IWorkspaceEditDto = { edits: [] };
for (let edit of edits) {
let { edits } = typeConverter.WorkspaceEdit.from(edit, this._extHostDocumentsAndEditors);
allEdits.push(edits);
dto.edits = dto.edits.concat(edits);
}
return this._mainThreadTextEditors.$tryApplyWorkspaceEdit({ edits: flatten(allEdits) });
return this._mainThreadTextEditors.$tryApplyWorkspaceEdit(dto);
}
}
}

View File

@@ -1120,7 +1120,7 @@ class ColorProviderAdapter {
provideColors(resource: URI, token: CancellationToken): Promise<extHostProtocol.IRawColorInfo[]> {
const doc = this._documents.getDocument(resource);
return asPromise(() => this._provider.provideDocumentColors(doc, token)).then(colors => {
if (!Array.isArray<vscode.ColorInformation>(colors)) {
if (!Array.isArray(colors)) {
return [];
}

File diff suppressed because it is too large Load Diff

View File

@@ -516,6 +516,7 @@ class ExtHostSourceControl implements vscode.SourceControl {
}
this._proxy.$registerGroups(this.handle, groups, splices);
this.createdResourceGroups.clear();
}
@debounce(100)

View File

@@ -269,8 +269,8 @@ export namespace TaskDTO {
presentationOptions: TaskPresentationOptionsDTO.from(value.presentationOptions),
problemMatchers: value.problemMatchers,
hasDefinedMatchers: (value as types.Task).hasDefinedMatchers,
runOptions: (<vscode.Task>value).runOptions ? (<vscode.Task>value).runOptions : { reevaluateOnRerun: true },
detail: (<vscode.Task2>value).detail
runOptions: value.runOptions ? value.runOptions : { reevaluateOnRerun: true },
detail: value.detail
};
return result;
}

View File

@@ -339,6 +339,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
public get onDidWriteTerminalData(): Event<vscode.TerminalDataWriteEvent> { return this._onDidWriteTerminalData && this._onDidWriteTerminalData.event; }
constructor(
supportsProcesses: boolean,
@IExtHostRpcService extHostRpc: IExtHostRpcService
) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadTerminalService);
@@ -347,6 +348,7 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
onFirstListenerAdd: () => this._proxy.$startSendingDataEvents(),
onLastListenerRemove: () => this._proxy.$stopSendingDataEvents()
});
this._proxy.$registerProcessSupport(supportsProcesses);
}
public abstract createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal;
@@ -805,6 +807,12 @@ export class EnvironmentVariableCollection implements vscode.EnvironmentVariable
}
export class WorkerExtHostTerminalService extends BaseExtHostTerminalService {
constructor(
@IExtHostRpcService extHostRpc: IExtHostRpcService
) {
super(false, extHostRpc);
}
public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
throw new NotSupportedError();
}

View File

@@ -7,6 +7,7 @@ import { Emitter, Event } from 'vs/base/common/event';
import * as arrays from 'vs/base/common/arrays';
import { ExtHostEditorsShape, IEditorPropertiesChangeData, IMainContext, ITextDocumentShowOptions, ITextEditorPositionData, MainContext, MainThreadTextEditorsShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
import { ExtHostTextEditor, TextEditorDecorationType } from 'vs/workbench/api/common/extHostTextEditor';
import * as TypeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { TextEditorSelectionChangeKind } from 'vs/workbench/api/common/extHostTypes';
@@ -28,16 +29,15 @@ export class ExtHostEditors implements ExtHostEditorsShape {
readonly onDidChangeActiveTextEditor: Event<vscode.TextEditor | undefined> = this._onDidChangeActiveTextEditor.event;
readonly onDidChangeVisibleTextEditors: Event<vscode.TextEditor[]> = this._onDidChangeVisibleTextEditors.event;
private _proxy: MainThreadTextEditorsShape;
private _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors;
private readonly _proxy: MainThreadTextEditorsShape;
constructor(
mainContext: IMainContext,
extHostDocumentsAndEditors: ExtHostDocumentsAndEditors,
private readonly _extHostDocumentsAndEditors: ExtHostDocumentsAndEditors,
private readonly _extHostNotebooks: ExtHostNotebookController,
) {
this._proxy = mainContext.getProxy(MainContext.MainThreadTextEditors);
this._extHostDocumentsAndEditors = extHostDocumentsAndEditors;
this._extHostDocumentsAndEditors.onDidChangeVisibleTextEditors(e => this._onDidChangeVisibleTextEditors.fire(e));
this._extHostDocumentsAndEditors.onDidChangeActiveTextEditor(e => this._onDidChangeActiveTextEditor.fire(e));
@@ -93,7 +93,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
}
applyWorkspaceEdit(edit: vscode.WorkspaceEdit): Promise<boolean> {
const dto = TypeConverters.WorkspaceEdit.from(edit, this._extHostDocumentsAndEditors);
const dto = TypeConverters.WorkspaceEdit.from(edit, this._extHostDocumentsAndEditors, this._extHostNotebooks);
return this._proxy.$tryApplyWorkspaceEdit(dto);
}

View File

@@ -31,6 +31,7 @@ import { LogLevel as _MainLogLevel } from 'vs/platform/log/common/log';
import { coalesce, isNonEmptyArray } from 'vs/base/common/arrays';
import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions';
import { CommandsConverter } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostNotebookController } from 'vs/workbench/api/common/extHostNotebook';
export interface PositionLike {
line: number;
@@ -505,32 +506,42 @@ export namespace TextEdit {
}
export namespace WorkspaceEdit {
export function from(value: vscode.WorkspaceEdit, documents?: ExtHostDocumentsAndEditors): extHostProtocol.IWorkspaceEditDto {
export function from(value: vscode.WorkspaceEdit, documents?: ExtHostDocumentsAndEditors, notebooks?: ExtHostNotebookController): extHostProtocol.IWorkspaceEditDto {
const result: extHostProtocol.IWorkspaceEditDto = {
edits: []
};
if (value instanceof types.WorkspaceEdit) {
for (let entry of value.allEntries()) {
for (let entry of value._allEntries()) {
if (entry._type === 1) {
if (entry._type === types.FileEditType.File) {
// file operation
result.edits.push(<extHostProtocol.IWorkspaceFileEditDto>{
_type: extHostProtocol.WorkspaceEditType.File,
oldUri: entry.from,
newUri: entry.to,
options: entry.options,
metadata: entry.metadata
});
} else {
} else if (entry._type === types.FileEditType.Text) {
// text edits
const doc = documents?.getDocument(entry.uri);
result.edits.push(<extHostProtocol.IWorkspaceTextEditDto>{
_type: extHostProtocol.WorkspaceEditType.Text,
resource: entry.uri,
edit: TextEdit.from(entry.edit),
modelVersionId: doc?.version,
metadata: entry.metadata
});
} else if (entry._type === types.FileEditType.Cell) {
result.edits.push(<extHostProtocol.IWorkspaceCellEditDto>{
_type: extHostProtocol.WorkspaceEditType.Cell,
resource: entry.uri,
edit: entry.edit,
metadata: entry.metadata,
modelVersionId: notebooks?.lookupNotebookDocument(entry.uri)?.notebookDocument.version
});
}
}
}
@@ -1281,3 +1292,58 @@ export namespace LogLevel {
}
}
}
export namespace NotebookExclusiveDocumentPattern {
export function from(pattern: { include: vscode.GlobPattern | undefined, exclude: vscode.GlobPattern | undefined }): { include: string | types.RelativePattern | undefined, exclude: string | types.RelativePattern | undefined };
export function from(pattern: vscode.GlobPattern): string | types.RelativePattern;
export function from(pattern: undefined): undefined;
export function from(pattern: { include: vscode.GlobPattern | undefined | null, exclude: vscode.GlobPattern | undefined } | vscode.GlobPattern | undefined): string | types.RelativePattern | { include: string | types.RelativePattern | undefined, exclude: string | types.RelativePattern | undefined } | undefined;
export function from(pattern: { include: vscode.GlobPattern | undefined | null, exclude: vscode.GlobPattern | undefined } | vscode.GlobPattern | undefined): string | types.RelativePattern | { include: string | types.RelativePattern | undefined, exclude: string | types.RelativePattern | undefined } | undefined {
if (pattern === null || pattern === undefined) {
return undefined;
}
if (pattern instanceof types.RelativePattern) {
return pattern;
}
if (typeof pattern === 'string') {
return pattern;
}
if (isRelativePattern(pattern)) {
return new types.RelativePattern(pattern.base, pattern.pattern);
}
if (isExclusivePattern(pattern)) {
return {
include: GlobPattern.from(pattern.include) || undefined,
exclude: GlobPattern.from(pattern.exclude) || undefined
};
}
return undefined; // preserve `undefined`
}
function isExclusivePattern(obj: any): obj is { include: types.RelativePattern | undefined | null, exclude: types.RelativePattern | undefined | null } {
const ep = obj as { include: vscode.GlobPattern, exclude: vscode.GlobPattern };
const include = GlobPattern.from(ep.include);
if (!(include && include instanceof types.RelativePattern || typeof include === 'string')) {
return false;
}
const exclude = GlobPattern.from(ep.exclude);
if (!(exclude && exclude instanceof types.RelativePattern || typeof exclude === 'string')) {
return false;
}
return true;
}
function isRelativePattern(obj: any): obj is vscode.RelativePattern {
const rp = obj as vscode.RelativePattern;
return rp && typeof rp.base === 'string' && typeof rp.pattern === 'string';
}
}

View File

@@ -3,17 +3,19 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { coalesce, equals } from 'vs/base/common/arrays';
import { coalesceInPlace, equals } from 'vs/base/common/arrays';
import { escapeCodicons } from 'vs/base/common/codicons';
import { illegalArgument } from 'vs/base/common/errors';
import { IRelativePattern } from 'vs/base/common/glob';
import { isMarkdownString } from 'vs/base/common/htmlContent';
import { ResourceMap } from 'vs/base/common/map';
import { startsWith } from 'vs/base/common/strings';
import { isStringArray } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import { FileSystemProviderErrorCode, markAsFileSystemProviderError } from 'vs/platform/files/common/files';
import { RemoteAuthorityResolverErrorCode } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { addIdToOutput, CellEditType, ICellEditOperation } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import type * as vscode from 'vscode';
function es5ClassCompat(target: Function): any {
@@ -575,8 +577,14 @@ export interface IFileOperationOptions {
recursive?: boolean;
}
export const enum FileEditType {
File = 1,
Text = 2,
Cell = 3
}
export interface IFileOperation {
_type: 1;
_type: FileEditType.File;
from?: URI;
to?: URI;
options?: IFileOperationOptions;
@@ -584,31 +592,61 @@ export interface IFileOperation {
}
export interface IFileTextEdit {
_type: 2;
_type: FileEditType.Text;
uri: URI;
edit: TextEdit;
metadata?: vscode.WorkspaceEditEntryMetadata;
}
export interface IFileCellEdit {
_type: FileEditType.Cell;
uri: URI;
edit: ICellEditOperation;
metadata?: vscode.WorkspaceEditEntryMetadata;
}
@es5ClassCompat
export class WorkspaceEdit implements vscode.WorkspaceEdit {
private _edits = new Array<IFileOperation | IFileTextEdit>();
private readonly _edits = new Array<IFileOperation | IFileTextEdit | IFileCellEdit>();
_allEntries(): ReadonlyArray<IFileTextEdit | IFileOperation | IFileCellEdit> {
return this._edits;
}
// --- file
renameFile(from: vscode.Uri, to: vscode.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean; }, metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({ _type: 1, from, to, options, metadata });
this._edits.push({ _type: FileEditType.File, from, to, options, metadata });
}
createFile(uri: vscode.Uri, options?: { overwrite?: boolean, ignoreIfExists?: boolean; }, metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({ _type: 1, from: undefined, to: uri, options, metadata });
this._edits.push({ _type: FileEditType.File, from: undefined, to: uri, options, metadata });
}
deleteFile(uri: vscode.Uri, options?: { recursive?: boolean, ignoreIfNotExists?: boolean; }, metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({ _type: 1, from: uri, to: undefined, options, metadata });
this._edits.push({ _type: FileEditType.File, from: uri, to: undefined, options, metadata });
}
// --- cell
replaceCells(uri: URI, start: number, end: number, cells: vscode.NotebookCellData[], metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Replace, index: start, count: end - start, cells: cells.map(cell => ({ ...cell, outputs: cell.outputs.map(output => addIdToOutput(output)) })) } });
}
replaceCellOutput(uri: URI, index: number, outputs: vscode.CellOutput[], metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Output, index, outputs: outputs.map(output => addIdToOutput(output)) } });
}
replaceCellMetadata(uri: URI, index: number, cellMetadata: vscode.NotebookCellMetadata, metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Metadata, index, metadata: cellMetadata } });
}
// --- text
replace(uri: URI, range: Range, newText: string, metadata?: vscode.WorkspaceEditEntryMetadata): void {
this._edits.push({ _type: 2, uri, edit: new TextEdit(range, newText), metadata });
this._edits.push({ _type: FileEditType.Text, uri, edit: new TextEdit(range, newText), metadata });
}
insert(resource: URI, position: Position, newText: string, metadata?: vscode.WorkspaceEditEntryMetadata): void {
@@ -619,8 +657,10 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
this.replace(resource, range, '', metadata);
}
// --- text (Maplike)
has(uri: URI): boolean {
return this._edits.some(edit => edit._type === 2 && edit.uri.toString() === uri.toString());
return this._edits.some(edit => edit._type === FileEditType.Text && edit.uri.toString() === uri.toString());
}
set(uri: URI, edits: TextEdit[]): void {
@@ -628,16 +668,16 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
// remove all text edits for `uri`
for (let i = 0; i < this._edits.length; i++) {
const element = this._edits[i];
if (element._type === 2 && element.uri.toString() === uri.toString()) {
if (element._type === FileEditType.Text && element.uri.toString() === uri.toString()) {
this._edits[i] = undefined!; // will be coalesced down below
}
}
this._edits = coalesce(this._edits);
coalesceInPlace(this._edits);
} else {
// append edit to the end
for (const edit of edits) {
if (edit) {
this._edits.push({ _type: 2, uri, edit });
this._edits.push({ _type: FileEditType.Text, uri, edit });
}
}
}
@@ -646,7 +686,7 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
get(uri: URI): TextEdit[] {
const res: TextEdit[] = [];
for (let candidate of this._edits) {
if (candidate._type === 2 && candidate.uri.toString() === uri.toString()) {
if (candidate._type === FileEditType.Text && candidate.uri.toString() === uri.toString()) {
res.push(candidate.edit);
}
}
@@ -654,13 +694,13 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
}
entries(): [URI, TextEdit[]][] {
const textEdits = new Map<string, [URI, TextEdit[]]>();
const textEdits = new ResourceMap<[URI, TextEdit[]]>();
for (let candidate of this._edits) {
if (candidate._type === 2) {
let textEdit = textEdits.get(candidate.uri.toString());
if (candidate._type === FileEditType.Text) {
let textEdit = textEdits.get(candidate.uri);
if (!textEdit) {
textEdit = [candidate.uri, []];
textEdits.set(candidate.uri.toString(), textEdit);
textEdits.set(candidate.uri, textEdit);
}
textEdit[1].push(candidate.edit);
}
@@ -668,22 +708,6 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
return [...textEdits.values()];
}
allEntries(): ReadonlyArray<IFileTextEdit | IFileOperation> {
return this._edits;
}
// _allEntries(): ([URI, TextEdit] | [URI?, URI?, IFileOperationOptions?])[] {
// const res: ([URI, TextEdit] | [URI?, URI?, IFileOperationOptions?])[] = [];
// for (let edit of this._edits) {
// if (edit._type === 1) {
// res.push([edit.from, edit.to, edit.options]);
// } else {
// res.push([edit.uri, edit.edit]);
// }
// }
// return res;
// }
get size(): number {
return this.entries().length;
}
@@ -1850,7 +1874,7 @@ export class CustomExecution implements vscode.CustomExecution {
}
@es5ClassCompat
export class Task implements vscode.Task2 {
export class Task implements vscode.Task {
private static ExtensionCallbackType: string = 'customExecution';
private static ProcessType: string = 'process';
@@ -2756,6 +2780,18 @@ export enum NotebookRunState {
Idle = 2
}
export enum NotebookCellStatusBarAlignment {
Left = 1,
Right = 2
}
export enum NotebookEditorRevealType {
Default = 0,
InCenter = 1,
InCenterIfOutsideViewport = 2
}
//#endregion
//#region Timeline

View File

@@ -4,14 +4,11 @@
*--------------------------------------------------------------------------------------------*/
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import * as modes from 'vs/editor/common/modes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
import { IExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { asWebviewUri, WebviewInitData } from 'vs/workbench/api/common/shared/webview';
import type * as vscode from 'vscode';
@@ -19,7 +16,7 @@ import * as extHostProtocol from './extHost.protocol';
export class ExtHostWebview implements vscode.Webview {
readonly #handle: extHostProtocol.WebviewPanelHandle;
readonly #handle: extHostProtocol.WebviewHandle;
readonly #proxy: extHostProtocol.MainThreadWebviewsShape;
readonly #deprecationService: IExtHostApiDeprecationService;
@@ -33,7 +30,7 @@ export class ExtHostWebview implements vscode.Webview {
#hasCalledAsWebviewUri = false;
constructor(
handle: extHostProtocol.WebviewPanelHandle,
handle: extHostProtocol.WebviewHandle,
proxy: extHostProtocol.MainThreadWebviewsShape,
options: vscode.WebviewOptions,
initData: WebviewInitData,
@@ -114,169 +111,11 @@ export class ExtHostWebview implements vscode.Webview {
}
}
type IconPath = URI | { light: URI, dark: URI };
class ExtHostWebviewPanel extends Disposable implements vscode.WebviewPanel {
readonly #handle: extHostProtocol.WebviewPanelHandle;
readonly #proxy: extHostProtocol.MainThreadWebviewsShape;
readonly #viewType: string;
readonly #webview: ExtHostWebview;
readonly #options: vscode.WebviewPanelOptions;
#title: string;
#iconPath?: IconPath;
#viewColumn: vscode.ViewColumn | undefined = undefined;
#visible: boolean = true;
#active: boolean = true;
#isDisposed: boolean = false;
readonly #onDidDispose = this._register(new Emitter<void>());
public readonly onDidDispose = this.#onDidDispose.event;
readonly #onDidChangeViewState = this._register(new Emitter<vscode.WebviewPanelOnDidChangeViewStateEvent>());
public readonly onDidChangeViewState = this.#onDidChangeViewState.event;
constructor(
handle: extHostProtocol.WebviewPanelHandle,
proxy: extHostProtocol.MainThreadWebviewsShape,
viewType: string,
title: string,
viewColumn: vscode.ViewColumn | undefined,
editorOptions: vscode.WebviewPanelOptions,
webview: ExtHostWebview
) {
super();
this.#handle = handle;
this.#proxy = proxy;
this.#viewType = viewType;
this.#options = editorOptions;
this.#viewColumn = viewColumn;
this.#title = title;
this.#webview = webview;
}
public dispose() {
if (this.#isDisposed) {
return;
}
this.#isDisposed = true;
this.#onDidDispose.fire();
this.#proxy.$disposeWebview(this.#handle);
this.#webview.dispose();
super.dispose();
}
get webview() {
this.assertNotDisposed();
return this.#webview;
}
get viewType(): string {
this.assertNotDisposed();
return this.#viewType;
}
get title(): string {
this.assertNotDisposed();
return this.#title;
}
set title(value: string) {
this.assertNotDisposed();
if (this.#title !== value) {
this.#title = value;
this.#proxy.$setTitle(this.#handle, value);
}
}
get iconPath(): IconPath | undefined {
this.assertNotDisposed();
return this.#iconPath;
}
set iconPath(value: IconPath | undefined) {
this.assertNotDisposed();
if (this.#iconPath !== value) {
this.#iconPath = value;
this.#proxy.$setIconPath(this.#handle, URI.isUri(value) ? { light: value, dark: value } : value);
}
}
get options() {
return this.#options;
}
get viewColumn(): vscode.ViewColumn | undefined {
this.assertNotDisposed();
if (typeof this.#viewColumn === 'number' && this.#viewColumn < 0) {
// We are using a symbolic view column
// Return undefined instead to indicate that the real view column is currently unknown but will be resolved.
return undefined;
}
return this.#viewColumn;
}
public get active(): boolean {
this.assertNotDisposed();
return this.#active;
}
public get visible(): boolean {
this.assertNotDisposed();
return this.#visible;
}
_updateViewState(newState: { active: boolean; visible: boolean; viewColumn: vscode.ViewColumn; }) {
if (this.#isDisposed) {
return;
}
if (this.active !== newState.active || this.visible !== newState.visible || this.viewColumn !== newState.viewColumn) {
this.#active = newState.active;
this.#visible = newState.visible;
this.#viewColumn = newState.viewColumn;
this.#onDidChangeViewState.fire({ webviewPanel: this });
}
}
public postMessage(message: any): Promise<boolean> {
this.assertNotDisposed();
return this.#proxy.$postMessage(this.#handle, message);
}
public reveal(viewColumn?: vscode.ViewColumn, preserveFocus?: boolean): void {
this.assertNotDisposed();
this.#proxy.$reveal(this.#handle, {
viewColumn: viewColumn ? typeConverters.ViewColumn.from(viewColumn) : undefined,
preserveFocus: !!preserveFocus
});
}
private assertNotDisposed() {
if (this.#isDisposed) {
throw new Error('Webview is disposed');
}
}
}
export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
private static newHandle(): extHostProtocol.WebviewPanelHandle {
return generateUuid();
}
private readonly _proxy: extHostProtocol.MainThreadWebviewsShape;
private readonly _webviews = new Map<extHostProtocol.WebviewPanelHandle, ExtHostWebview>();
private readonly _webviewPanels = new Map<extHostProtocol.WebviewPanelHandle, ExtHostWebviewPanel>();
private readonly _webviewProxy: extHostProtocol.MainThreadWebviewsShape;
private readonly _webviews = new Map<extHostProtocol.WebviewHandle, ExtHostWebview>();
constructor(
mainContext: extHostProtocol.IMainContext,
@@ -285,33 +124,11 @@ export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
private readonly _logService: ILogService,
private readonly _deprecationService: IExtHostApiDeprecationService,
) {
this._proxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadWebviews);
}
public createWebviewPanel(
extension: IExtensionDescription,
viewType: string,
title: string,
showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean },
options: (vscode.WebviewPanelOptions & vscode.WebviewOptions) = {},
): vscode.WebviewPanel {
const viewColumn = typeof showOptions === 'object' ? showOptions.viewColumn : showOptions;
const webviewShowOptions = {
viewColumn: typeConverters.ViewColumn.from(viewColumn),
preserveFocus: typeof showOptions === 'object' && !!showOptions.preserveFocus
};
const handle = ExtHostWebviews.newHandle();
this._proxy.$createWebviewPanel(toExtensionData(extension), handle, viewType, title, webviewShowOptions, convertWebviewOptions(extension, this.workspace, options));
const webview = this.createNewWebview(handle, options, extension);
const panel = this.createNewWebviewPanel(handle, viewType, title, viewColumn, options, webview);
return panel;
this._webviewProxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadWebviews);
}
public $onMessage(
handle: extHostProtocol.WebviewPanelHandle,
handle: extHostProtocol.WebviewHandle,
message: any
): void {
const webview = this.getWebview(handle);
@@ -321,61 +138,14 @@ export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
}
public $onMissingCsp(
_handle: extHostProtocol.WebviewPanelHandle,
_handle: extHostProtocol.WebviewHandle,
extensionId: string
): void {
this._logService.warn(`${extensionId} created a webview without a content security policy: https://aka.ms/vscode-webview-missing-csp`);
}
public $onDidChangeWebviewPanelViewStates(newStates: extHostProtocol.WebviewPanelViewStateData): void {
const handles = Object.keys(newStates);
// Notify webviews of state changes in the following order:
// - Non-visible
// - Visible
// - Active
handles.sort((a, b) => {
const stateA = newStates[a];
const stateB = newStates[b];
if (stateA.active) {
return 1;
}
if (stateB.active) {
return -1;
}
return (+stateA.visible) - (+stateB.visible);
});
for (const handle of handles) {
const panel = this.getWebviewPanel(handle);
if (!panel) {
continue;
}
const newState = newStates[handle];
panel._updateViewState({
active: newState.active,
visible: newState.visible,
viewColumn: typeConverters.ViewColumn.to(newState.position),
});
}
}
async $onDidDisposeWebviewPanel(handle: extHostProtocol.WebviewPanelHandle): Promise<void> {
const panel = this.getWebviewPanel(handle);
panel?.dispose();
this._webviewPanels.delete(handle);
this._webviews.delete(handle);
}
public createNewWebviewPanel(webviewHandle: string, viewType: string, title: string, position: number, options: modes.IWebviewOptions & modes.IWebviewPanelOptions, webview: ExtHostWebview) {
const panel = new ExtHostWebviewPanel(webviewHandle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
this._webviewPanels.set(webviewHandle, panel);
return panel;
}
public createNewWebview(handle: string, options: modes.IWebviewOptions & modes.IWebviewPanelOptions, extension: IExtensionDescription): ExtHostWebview {
const webview = new ExtHostWebview(handle, this._proxy, reviveOptions(options), this.initData, this.workspace, extension, this._deprecationService);
const webview = new ExtHostWebview(handle, this._webviewProxy, reviveOptions(options), this.initData, this.workspace, extension, this._deprecationService);
this._webviews.set(handle, webview);
webview._onDidDispose(() => { this._webviews.delete(handle); });
@@ -383,12 +153,12 @@ export class ExtHostWebviews implements extHostProtocol.ExtHostWebviewsShape {
return webview;
}
private getWebview(handle: extHostProtocol.WebviewPanelHandle): ExtHostWebview | undefined {
return this._webviews.get(handle);
public deleteWebview(handle: string) {
this._webviews.delete(handle);
}
public getWebviewPanel(handle: extHostProtocol.WebviewPanelHandle): ExtHostWebviewPanel | undefined {
return this._webviewPanels.get(handle);
private getWebview(handle: extHostProtocol.WebviewHandle): ExtHostWebview | undefined {
return this._webviews.get(handle);
}
}
@@ -396,7 +166,7 @@ export function toExtensionData(extension: IExtensionDescription): extHostProtoc
return { id: extension.identifier, location: extension.extensionLocation };
}
function convertWebviewOptions(
export function convertWebviewOptions(
extension: IExtensionDescription,
workspace: IExtHostWorkspace | undefined,
options: vscode.WebviewPanelOptions & vscode.WebviewOptions,

View File

@@ -0,0 +1,299 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import * as modes from 'vs/editor/common/modes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
import { convertWebviewOptions, ExtHostWebview, ExtHostWebviews, toExtensionData } from 'vs/workbench/api/common/extHostWebview';
import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import type * as vscode from 'vscode';
import * as extHostProtocol from './extHost.protocol';
import * as extHostTypes from './extHostTypes';
type IconPath = URI | { light: URI, dark: URI };
class ExtHostWebviewPanel extends Disposable implements vscode.WebviewPanel {
readonly #handle: extHostProtocol.WebviewHandle;
readonly #proxy: extHostProtocol.MainThreadWebviewPanelsShape;
readonly #viewType: string;
readonly #webview: ExtHostWebview;
readonly #options: vscode.WebviewPanelOptions;
#title: string;
#iconPath?: IconPath;
#viewColumn: vscode.ViewColumn | undefined = undefined;
#visible: boolean = true;
#active: boolean = true;
#isDisposed: boolean = false;
readonly #onDidDispose = this._register(new Emitter<void>());
public readonly onDidDispose = this.#onDidDispose.event;
readonly #onDidChangeViewState = this._register(new Emitter<vscode.WebviewPanelOnDidChangeViewStateEvent>());
public readonly onDidChangeViewState = this.#onDidChangeViewState.event;
constructor(
handle: extHostProtocol.WebviewHandle,
proxy: extHostProtocol.MainThreadWebviewPanelsShape,
viewType: string,
title: string,
viewColumn: vscode.ViewColumn | undefined,
editorOptions: vscode.WebviewPanelOptions,
webview: ExtHostWebview
) {
super();
this.#handle = handle;
this.#proxy = proxy;
this.#viewType = viewType;
this.#options = editorOptions;
this.#viewColumn = viewColumn;
this.#title = title;
this.#webview = webview;
}
public dispose() {
if (this.#isDisposed) {
return;
}
this.#isDisposed = true;
this.#onDidDispose.fire();
this.#proxy.$disposeWebview(this.#handle);
this.#webview.dispose();
super.dispose();
}
get webview() {
this.assertNotDisposed();
return this.#webview;
}
get viewType(): string {
this.assertNotDisposed();
return this.#viewType;
}
get title(): string {
this.assertNotDisposed();
return this.#title;
}
set title(value: string) {
this.assertNotDisposed();
if (this.#title !== value) {
this.#title = value;
this.#proxy.$setTitle(this.#handle, value);
}
}
get iconPath(): IconPath | undefined {
this.assertNotDisposed();
return this.#iconPath;
}
set iconPath(value: IconPath | undefined) {
this.assertNotDisposed();
if (this.#iconPath !== value) {
this.#iconPath = value;
this.#proxy.$setIconPath(this.#handle, URI.isUri(value) ? { light: value, dark: value } : value);
}
}
get options() {
return this.#options;
}
get viewColumn(): vscode.ViewColumn | undefined {
this.assertNotDisposed();
if (typeof this.#viewColumn === 'number' && this.#viewColumn < 0) {
// We are using a symbolic view column
// Return undefined instead to indicate that the real view column is currently unknown but will be resolved.
return undefined;
}
return this.#viewColumn;
}
public get active(): boolean {
this.assertNotDisposed();
return this.#active;
}
public get visible(): boolean {
this.assertNotDisposed();
return this.#visible;
}
_updateViewState(newState: { active: boolean; visible: boolean; viewColumn: vscode.ViewColumn; }) {
if (this.#isDisposed) {
return;
}
if (this.active !== newState.active || this.visible !== newState.visible || this.viewColumn !== newState.viewColumn) {
this.#active = newState.active;
this.#visible = newState.visible;
this.#viewColumn = newState.viewColumn;
this.#onDidChangeViewState.fire({ webviewPanel: this });
}
}
public reveal(viewColumn?: vscode.ViewColumn, preserveFocus?: boolean): void {
this.assertNotDisposed();
this.#proxy.$reveal(this.#handle, {
viewColumn: viewColumn ? typeConverters.ViewColumn.from(viewColumn) : undefined,
preserveFocus: !!preserveFocus
});
}
private assertNotDisposed() {
if (this.#isDisposed) {
throw new Error('Webview is disposed');
}
}
}
export class ExtHostWebviewPanels implements extHostProtocol.ExtHostWebviewPanelsShape {
private static newHandle(): extHostProtocol.WebviewHandle {
return generateUuid();
}
private readonly _proxy: extHostProtocol.MainThreadWebviewPanelsShape;
private readonly _webviewPanels = new Map<extHostProtocol.WebviewHandle, ExtHostWebviewPanel>();
private readonly _serializers = new Map<string, {
readonly serializer: vscode.WebviewPanelSerializer;
readonly extension: IExtensionDescription;
}>();
constructor(
mainContext: extHostProtocol.IMainContext,
private readonly webviews: ExtHostWebviews,
private readonly workspace: IExtHostWorkspace | undefined,
) {
this._proxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadWebviewPanels);
}
public createWebviewPanel(
extension: IExtensionDescription,
viewType: string,
title: string,
showOptions: vscode.ViewColumn | { viewColumn: vscode.ViewColumn, preserveFocus?: boolean },
options: (vscode.WebviewPanelOptions & vscode.WebviewOptions) = {},
): vscode.WebviewPanel {
const viewColumn = typeof showOptions === 'object' ? showOptions.viewColumn : showOptions;
const webviewShowOptions = {
viewColumn: typeConverters.ViewColumn.from(viewColumn),
preserveFocus: typeof showOptions === 'object' && !!showOptions.preserveFocus
};
const handle = ExtHostWebviewPanels.newHandle();
this._proxy.$createWebviewPanel(toExtensionData(extension), handle, viewType, title, webviewShowOptions, convertWebviewOptions(extension, this.workspace, options));
const webview = this.webviews.createNewWebview(handle, options, extension);
const panel = this.createNewWebviewPanel(handle, viewType, title, viewColumn, options, webview);
return panel;
}
public $onDidChangeWebviewPanelViewStates(newStates: extHostProtocol.WebviewPanelViewStateData): void {
const handles = Object.keys(newStates);
// Notify webviews of state changes in the following order:
// - Non-visible
// - Visible
// - Active
handles.sort((a, b) => {
const stateA = newStates[a];
const stateB = newStates[b];
if (stateA.active) {
return 1;
}
if (stateB.active) {
return -1;
}
return (+stateA.visible) - (+stateB.visible);
});
for (const handle of handles) {
const panel = this.getWebviewPanel(handle);
if (!panel) {
continue;
}
const newState = newStates[handle];
panel._updateViewState({
active: newState.active,
visible: newState.visible,
viewColumn: typeConverters.ViewColumn.to(newState.position),
});
}
}
async $onDidDisposeWebviewPanel(handle: extHostProtocol.WebviewHandle): Promise<void> {
const panel = this.getWebviewPanel(handle);
panel?.dispose();
this._webviewPanels.delete(handle);
this.webviews.deleteWebview(handle);
}
public registerWebviewPanelSerializer(
extension: IExtensionDescription,
viewType: string,
serializer: vscode.WebviewPanelSerializer
): vscode.Disposable {
if (this._serializers.has(viewType)) {
throw new Error(`Serializer for '${viewType}' already registered`);
}
this._serializers.set(viewType, { serializer, extension });
this._proxy.$registerSerializer(viewType);
return new extHostTypes.Disposable(() => {
this._serializers.delete(viewType);
this._proxy.$unregisterSerializer(viewType);
});
}
async $deserializeWebviewPanel(
webviewHandle: extHostProtocol.WebviewHandle,
viewType: string,
title: string,
state: any,
position: EditorViewColumn,
options: modes.IWebviewOptions & modes.IWebviewPanelOptions
): Promise<void> {
const entry = this._serializers.get(viewType);
if (!entry) {
throw new Error(`No serializer found for '${viewType}'`);
}
const { serializer, extension } = entry;
const webview = this.webviews.createNewWebview(webviewHandle, options, extension);
const revivedPanel = this.createNewWebviewPanel(webviewHandle, viewType, title, position, options, webview);
await serializer.deserializeWebviewPanel(revivedPanel, state);
}
public createNewWebviewPanel(webviewHandle: string, viewType: string, title: string, position: number, options: modes.IWebviewOptions & modes.IWebviewPanelOptions, webview: ExtHostWebview) {
const panel = new ExtHostWebviewPanel(webviewHandle, this._proxy, viewType, title, typeof position === 'number' && position >= 0 ? typeConverters.ViewColumn.to(position) : undefined, options, webview);
this._webviewPanels.set(webviewHandle, panel);
return panel;
}
public getWebviewPanel(handle: extHostProtocol.WebviewHandle): ExtHostWebviewPanel | undefined {
return this._webviewPanels.get(handle);
}
}

View File

@@ -1,66 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as modes from 'vs/editor/common/modes';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview';
import { EditorViewColumn } from 'vs/workbench/api/common/shared/editor';
import type * as vscode from 'vscode';
import * as extHostProtocol from './extHost.protocol';
import * as extHostTypes from './extHostTypes';
export class ExtHostWebviewSerializer implements extHostProtocol.ExtHostWebviewSerializerShape {
private readonly _proxy: extHostProtocol.MainThreadWebviewsShape;
private readonly _serializers = new Map<string, {
readonly serializer: vscode.WebviewPanelSerializer;
readonly extension: IExtensionDescription;
}>();
constructor(
mainContext: extHostProtocol.IMainContext,
private readonly _webviewService: ExtHostWebviews,
) {
this._proxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadWebviews);
}
public registerWebviewPanelSerializer(
extension: IExtensionDescription,
viewType: string,
serializer: vscode.WebviewPanelSerializer
): vscode.Disposable {
if (this._serializers.has(viewType)) {
throw new Error(`Serializer for '${viewType}' already registered`);
}
this._serializers.set(viewType, { serializer, extension });
this._proxy.$registerSerializer(viewType);
return new extHostTypes.Disposable(() => {
this._serializers.delete(viewType);
this._proxy.$unregisterSerializer(viewType);
});
}
async $deserializeWebviewPanel(
webviewHandle: extHostProtocol.WebviewPanelHandle,
viewType: string,
title: string,
state: any,
position: EditorViewColumn,
options: modes.IWebviewOptions & modes.IWebviewPanelOptions
): Promise<void> {
const entry = this._serializers.get(viewType);
if (!entry) {
throw new Error(`No serializer found for '${viewType}'`);
}
const { serializer, extension } = entry;
const webview = this._webviewService.createNewWebview(webviewHandle, options, extension);
const revivedPanel = this._webviewService.createNewWebviewPanel(webviewHandle, viewType, title, position, options, webview);
await serializer.deserializeWebviewPanel(revivedPanel, state);
}
}

View File

@@ -14,8 +14,8 @@ import * as extHostTypes from './extHostTypes';
class ExtHostWebviewView extends Disposable implements vscode.WebviewView {
readonly #handle: extHostProtocol.WebviewPanelHandle;
readonly #proxy: extHostProtocol.MainThreadWebviewsShape;
readonly #handle: extHostProtocol.WebviewHandle;
readonly #proxy: extHostProtocol.MainThreadWebviewViewsShape;
readonly #viewType: string;
readonly #webview: ExtHostWebview;
@@ -25,8 +25,8 @@ class ExtHostWebviewView extends Disposable implements vscode.WebviewView {
#title: string | undefined;
constructor(
handle: extHostProtocol.WebviewPanelHandle,
proxy: extHostProtocol.MainThreadWebviewsShape,
handle: extHostProtocol.WebviewHandle,
proxy: extHostProtocol.MainThreadWebviewViewsShape,
viewType: string,
webview: ExtHostWebview,
isVisible: boolean,
@@ -94,20 +94,20 @@ class ExtHostWebviewView extends Disposable implements vscode.WebviewView {
export class ExtHostWebviewViews implements extHostProtocol.ExtHostWebviewViewsShape {
private readonly _proxy: extHostProtocol.MainThreadWebviewsShape;
private readonly _proxy: extHostProtocol.MainThreadWebviewViewsShape;
private readonly _viewProviders = new Map<string, {
readonly provider: vscode.WebviewViewProvider;
readonly extension: IExtensionDescription;
}>();
private readonly _webviewViews = new Map<extHostProtocol.WebviewPanelHandle, ExtHostWebviewView>();
private readonly _webviewViews = new Map<extHostProtocol.WebviewHandle, ExtHostWebviewView>();
constructor(
mainContext: extHostProtocol.IMainContext,
private readonly _extHostWebview: ExtHostWebviews,
) {
this._proxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadWebviews);
this._proxy = mainContext.getProxy(extHostProtocol.MainContext.MainThreadWebviewViews);
}
public registerWebviewViewProvider(

View File

@@ -12,7 +12,7 @@ import { isFalsyOrWhitespace } from 'vs/base/common/strings';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
export class ExtHostWindow implements IExtHostWindow {
export class ExtHostWindow implements ExtHostWindowShape {
private static InitialState: WindowState = {
focused: true

View File

@@ -61,7 +61,12 @@ const apiMenus: IAPIMenu[] = [
{
key: 'debug/callstack/context',
id: MenuId.DebugCallStackContext,
description: localize('menus.debugCallstackContext', "The debug callstack context menu")
description: localize('menus.debugCallstackContext', "The debug callstack view context menu")
},
{
key: 'debug/variables/context',
id: MenuId.DebugVariablesContext,
description: localize('menus.debugVariablesContext', "The debug variables view context menu")
},
{
key: 'debug/toolBar',