Update to VS Code 1.52.1

This commit is contained in:
Asher
2021-02-09 16:08:37 +00:00
1351 changed files with 56560 additions and 38990 deletions

View File

@@ -65,6 +65,7 @@ import 'vs/server/browser/mainThreadNodeProxy';
import './mainThreadTunnelService';
import './mainThreadAuthentication';
import './mainThreadTimeline';
import './mainThreadTesting';
import 'vs/workbench/api/common/apiCommands';
export class ExtensionPoints implements IWorkbenchContribution {

View File

@@ -10,11 +10,10 @@ import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { IAuthenticationService, AllowedExtension, readAllowedExtensions, getAuthenticationProviderActivationEvent } from 'vs/workbench/services/authentication/browser/authenticationService';
import { ExtHostAuthenticationShape, ExtHostContext, IExtHostContext, MainContext, MainThreadAuthenticationShape } from '../common/extHost.protocol';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import Severity from 'vs/base/common/severity';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { fromNow } from 'vs/base/common/date';
import { ActivationKind, IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
@@ -23,7 +22,7 @@ import { IEncryptionService } from 'vs/workbench/services/encryption/common/encr
import { IProductService } from 'vs/platform/product/common/productService';
import { ICredentialsService } from 'vs/workbench/services/credentials/common/credentials';
const VSO_ALLOWED_EXTENSIONS = ['github.vscode-pull-request-github', 'github.vscode-pull-request-github-insiders', 'vscode.git', 'ms-vsonline.vsonline', 'vscode.github-browser', 'ms-vscode.github-browser'];
const VSO_ALLOWED_EXTENSIONS = ['github.vscode-pull-request-github', 'github.vscode-pull-request-github-insiders', 'vscode.git', 'ms-vsonline.vsonline', 'vscode.github-browser', 'ms-vscode.github-browser', 'github.codespaces'];
interface IAccountUsage {
extensionId: string;
@@ -70,7 +69,7 @@ function addAccountUsage(storageService: IStorageService, providerId: string, ac
});
}
storageService.store(accountKey, JSON.stringify(usages), StorageScope.GLOBAL);
storageService.store(accountKey, JSON.stringify(usages), StorageScope.GLOBAL, StorageTarget.MACHINE);
}
export class MainThreadAuthenticationProvider extends Disposable {
@@ -83,7 +82,6 @@ export class MainThreadAuthenticationProvider extends Disposable {
public readonly label: string,
public readonly supportsMultipleAccounts: boolean,
private readonly notificationService: INotificationService,
private readonly storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
private readonly storageService: IStorageService,
private readonly quickInputService: IQuickInputService,
private readonly dialogService: IDialogService
@@ -100,9 +98,15 @@ export class MainThreadAuthenticationProvider extends Disposable {
}
public manageTrustedExtensions(accountName: string) {
const allowedExtensions = readAllowedExtensions(this.storageService, this.id, accountName);
if (!allowedExtensions.length) {
this.dialogService.show(Severity.Info, nls.localize('noTrustedExtensions', "This account has not been used by any extensions."), []);
return;
}
const quickPick = this.quickInputService.createQuickPick<{ label: string, description: string, extension: AllowedExtension }>();
quickPick.canSelectMany = true;
const allowedExtensions = readAllowedExtensions(this.storageService, this.id, accountName);
const usages = readAccountUsages(this.storageService, this.id, accountName);
const items = allowedExtensions.map(extension => {
const usage = usages.find(usage => extension.id === usage.extensionId);
@@ -122,7 +126,7 @@ export class MainThreadAuthenticationProvider extends Disposable {
quickPick.onDidAccept(() => {
const updatedAllowedList = quickPick.selectedItems.map(item => item.extension);
this.storageService.store(`${this.id}-${accountName}`, JSON.stringify(updatedAllowedList), StorageScope.GLOBAL);
this.storageService.store(`${this.id}-${accountName}`, JSON.stringify(updatedAllowedList), StorageScope.GLOBAL, StorageTarget.USER);
quickPick.dispose();
});
@@ -153,8 +157,6 @@ export class MainThreadAuthenticationProvider extends Disposable {
} else {
this._accounts.set(session.account.label, [session.id]);
}
this.storageKeysSyncRegistryService.registerStorageKey({ key: `${this.id}-${session.account.label}`, version: 1 });
}
async signOut(accountName: string): Promise<void> {
@@ -171,6 +173,7 @@ export class MainThreadAuthenticationProvider extends Disposable {
if (result.confirmed) {
sessionsForAccount?.forEach(sessionId => this.logout(sessionId));
removeAccountUsage(this.storageService, this.id, accountName);
this.storageService.remove(`${this.id}-${accountName}`, StorageScope.GLOBAL);
}
}
@@ -220,7 +223,6 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
@IDialogService private readonly dialogService: IDialogService,
@IStorageService private readonly storageService: IStorageService,
@INotificationService private readonly notificationService: INotificationService,
@IStorageKeysSyncRegistryService private readonly storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
@IQuickInputService private readonly quickInputService: IQuickInputService,
@IExtensionService private readonly extensionService: IExtensionService,
@@ -259,7 +261,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
}
async $registerAuthenticationProvider(id: string, label: string, supportsMultipleAccounts: boolean): Promise<void> {
const provider = new MainThreadAuthenticationProvider(this._proxy, id, label, supportsMultipleAccounts, this.notificationService, this.storageKeysSyncRegistryService, this.storageService, this.quickInputService, this.dialogService);
const provider = new MainThreadAuthenticationProvider(this._proxy, id, label, supportsMultipleAccounts, this.notificationService, this.storageService, this.quickInputService, this.dialogService);
await provider.initialize();
this.authenticationService.registerAuthenticationProvider(id, provider);
}
@@ -383,10 +385,10 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
const allowList = readAllowedExtensions(this.storageService, providerId, accountName);
if (!allowList.find(allowed => allowed.id === extensionId)) {
allowList.push({ id: extensionId, name: extensionName });
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL, StorageTarget.USER);
}
this.storageService.store(`${extensionName}-${providerId}`, session.id, StorageScope.GLOBAL);
this.storageService.store(`${extensionName}-${providerId}`, session.id, StorageScope.GLOBAL, StorageTarget.MACHINE);
quickPick.dispose();
resolve(session);
@@ -435,7 +437,7 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
if (allow) {
addAccountUsage(this.storageService, providerId, accountName, extensionId, extensionName);
allowList.push({ id: extensionId, name: extensionName });
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL, StorageTarget.USER);
}
return allow;
@@ -458,10 +460,11 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
const allowList = readAllowedExtensions(this.storageService, providerId, accountName);
if (!allowList.find(allowed => allowed.id === extensionId)) {
allowList.push({ id: extensionId, name: extensionName });
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL);
this.storageService.store(`${providerId}-${accountName}`, JSON.stringify(allowList), StorageScope.GLOBAL, StorageTarget.USER);
}
this.storageService.store(`${extensionName}-${providerId}`, sessionId, StorageScope.GLOBAL);
this.storageService.store(`${extensionName}-${providerId}`, sessionId, StorageScope.GLOBAL, StorageTarget.MACHINE);
addAccountUsage(this.storageService, providerId, accountName, extensionId, extensionName);
}
private getFullKey(extensionId: string): string {

View File

@@ -37,8 +37,14 @@ export class MainThreadBulkEdits implements MainThreadBulkEditsShape {
dispose(): void { }
$tryApplyWorkspaceEdit(dto: IWorkspaceEditDto): Promise<boolean> {
$tryApplyWorkspaceEdit(dto: IWorkspaceEditDto, undoRedoGroupId?: number): Promise<boolean> {
const edits = reviveWorkspaceEditDto2(dto);
return this._bulkEditService.apply(edits).then(() => true, _err => false);
return this._bulkEditService.apply(edits, {
// having a undoRedoGroupId means that this is a nested workspace edit,
// e.g one from a onWill-handler and for now we need to forcefully suppress
// refactor previewing, see: https://github.com/microsoft/vscode/issues/111873#issuecomment-738739852
undoRedoGroupId,
suppressPreview: typeof undoRedoGroupId === 'number' ? true : undefined
}).then(() => true, _err => false);
}
}

View File

@@ -14,7 +14,7 @@ import { IActiveCodeEditor, IViewZone } from 'vs/editor/browser/editorBrowser';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { isEqual } from 'vs/base/common/resources';
// todo@joh move these things back into something like contrib/insets
// todo@jrieken move these things back into something like contrib/insets
class EditorWebviewZone implements IViewZone {
readonly domNode: HTMLElement;
@@ -73,7 +73,7 @@ export class MainThreadEditorInsets implements MainThreadEditorInsetsShape {
async $createEditorInset(handle: number, id: string, uri: UriComponents, line: number, height: number, options: modes.IWebviewOptions, extensionId: ExtensionIdentifier, extensionLocation: UriComponents): Promise<void> {
let editor: IActiveCodeEditor | undefined;
id = id.substr(0, id.indexOf(',')); //todo@joh HACK
id = id.substr(0, id.indexOf(',')); //todo@jrieken HACK
for (const candidate of this._editorService.listCodeEditors()) {
if (candidate.getId() === id && candidate.hasModel() && isEqual(candidate.getModel().uri, URI.revive(uri))) {

View File

@@ -34,23 +34,23 @@ export class MainThreadCommands implements MainThreadCommandsShape {
this._generateCommandsDocumentationRegistration.dispose();
}
private _generateCommandsDocumentation(): Promise<void> {
return this._proxy.$getContributedCommandHandlerDescriptions().then(result => {
// add local commands
const commands = CommandsRegistry.getCommands();
for (const [id, command] of commands) {
if (command.description) {
result[id] = command.description;
}
}
private async _generateCommandsDocumentation(): Promise<void> {
const result = await this._proxy.$getContributedCommandHandlerDescriptions();
// print all as markdown
const all: string[] = [];
for (let id in result) {
all.push('`' + id + '` - ' + _generateMarkdown(result[id]));
// add local commands
const commands = CommandsRegistry.getCommands();
for (const [id, command] of commands) {
if (command.description) {
result[id] = command.description;
}
console.log(all.join('\n'));
});
}
// print all as markdown
const all: string[] = [];
for (let id in result) {
all.push('`' + id + '` - ' + _generateMarkdown(result[id]));
}
console.log(all.join('\n'));
}
$registerCommand(id: string): void {

View File

@@ -21,6 +21,8 @@ import { ViewContainer, IViewContainersRegistry, Extensions as ViewExtensions, V
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { Codicon } from 'vs/base/common/codicons';
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
import { localize } from 'vs/nls';
export class MainThreadCommentThread implements modes.CommentThread {
@@ -351,6 +353,9 @@ export class MainThreadCommentController {
}
}
const commentsViewIcon = registerIcon('comments-view-icon', Codicon.commentDiscussion, localize('commentsViewIcon', 'View icon of the comments view.'));
@extHostNamedCustomer(MainContext.MainThreadComments)
export class MainThreadComments extends Disposable implements MainThreadCommentsShape {
private readonly _proxy: ExtHostCommentsShape;
@@ -472,7 +477,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments
ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [COMMENTS_VIEW_ID, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }]),
storageId: COMMENTS_VIEW_TITLE,
hideIfEmpty: true,
icon: Codicon.commentDiscussion.classNames,
icon: commentsViewIcon,
order: 10,
}, ViewContainerLocation.Panel);
@@ -482,7 +487,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments
canToggleVisibility: false,
ctorDescriptor: new SyncDescriptor(CommentsPanel),
canMoveView: true,
containerIcon: Codicon.commentDiscussion.classNames,
containerIcon: commentsViewIcon,
focusCommand: {
id: 'workbench.action.focusCommentsPanel'
}

View File

@@ -23,8 +23,7 @@ import { IUndoRedoService, UndoRedoElementType } from 'vs/platform/undoRedo/comm
import { MainThreadWebviewPanels } from 'vs/workbench/api/browser/mainThreadWebviewPanels';
import { MainThreadWebviews, reviveWebviewExtension } from 'vs/workbench/api/browser/mainThreadWebviews';
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
import { editorGroupToViewColumn } from 'vs/workbench/api/common/shared/editor';
import { IRevertOptions, ISaveOptions } from 'vs/workbench/common/editor';
import { editorGroupToViewColumn, IRevertOptions, ISaveOptions } from 'vs/workbench/common/editor';
import { CustomEditorInput } from 'vs/workbench/contrib/customEditor/browser/customEditorInput';
import { CustomDocumentBackupData } from 'vs/workbench/contrib/customEditor/browser/customEditorInputFactory';
import { ICustomEditorModel, ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor';
@@ -604,6 +603,10 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod
this._proxy.$backup(this._editorResource.toJSON(), this.viewType, token)));
this._hotExitState = pendingState;
token.onCancellationRequested(() => {
pendingState.operation.cancel();
});
try {
const backupId = await pendingState.operation;
// Make sure state has not changed in the meantime

View File

@@ -82,7 +82,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
// RPC methods (MainThreadDebugServiceShape)
public $registerDebugTypes(debugTypes: string[]) {
this._toDispose.add(this.debugService.getConfigurationManager().registerDebugAdapterFactory(debugTypes, this));
this._toDispose.add(this.debugService.getAdapterManager().registerDebugAdapterFactory(debugTypes, this));
}
public $startBreakpointEvents(): void {
@@ -155,7 +155,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
return Promise.resolve();
}
public $registerDebugConfigurationProvider(debugType: string, providerTriggerKind: DebugConfigurationProviderTriggerKind, hasProvide: boolean, hasResolve: boolean, hasResolve2: boolean, hasProvideDebugAdapter: boolean, handle: number): Promise<void> {
public $registerDebugConfigurationProvider(debugType: string, providerTriggerKind: DebugConfigurationProviderTriggerKind, hasProvide: boolean, hasResolve: boolean, hasResolve2: boolean, handle: number): Promise<void> {
const provider = <IDebugConfigurationProvider>{
type: debugType,
@@ -176,12 +176,6 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
return this._proxy.$resolveDebugConfigurationWithSubstitutedVariables(handle, folder, config, token);
};
}
if (hasProvideDebugAdapter) {
console.info('DebugConfigurationProvider.debugAdapterExecutable is deprecated and will be removed soon; please use DebugAdapterDescriptorFactory.createDebugAdapterDescriptor instead.');
provider.debugAdapterExecutable = (folder) => {
return this._proxy.$legacyDebugAdapterExecutable(handle, folder);
};
}
this._debugConfigurationProviders.set(handle, provider);
this._toDispose.add(this.debugService.getConfigurationManager().registerDebugConfigurationProvider(provider));
@@ -205,7 +199,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
}
};
this._debugAdapterDescriptorFactories.set(handle, provider);
this._toDispose.add(this.debugService.getConfigurationManager().registerDebugAdapterDescriptorFactory(provider));
this._toDispose.add(this.debugService.getAdapterManager().registerDebugAdapterDescriptorFactory(provider));
return Promise.resolve(undefined);
}
@@ -214,7 +208,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
const provider = this._debugAdapterDescriptorFactories.get(handle);
if (provider) {
this._debugAdapterDescriptorFactories.delete(handle);
this.debugService.getConfigurationManager().unregisterDebugAdapterDescriptorFactory(provider);
this.debugService.getAdapterManager().unregisterDebugAdapterDescriptorFactory(provider);
}
}

View File

@@ -23,12 +23,20 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape {
//
}
$showOpenDialog(options?: MainThreadDialogOpenOptions): Promise<URI[] | undefined> {
return Promise.resolve(this._fileDialogService.showOpenDialog(MainThreadDialogs._convertOpenOptions(options)));
async $showOpenDialog(options?: MainThreadDialogOpenOptions): Promise<URI[] | undefined> {
const convertedOptions = MainThreadDialogs._convertOpenOptions(options);
if (!convertedOptions.defaultUri) {
convertedOptions.defaultUri = await this._fileDialogService.defaultFilePath();
}
return Promise.resolve(this._fileDialogService.showOpenDialog(convertedOptions));
}
$showSaveDialog(options?: MainThreadDialogSaveOptions): Promise<URI | undefined> {
return Promise.resolve(this._fileDialogService.showSaveDialog(MainThreadDialogs._convertSaveOptions(options)));
async $showSaveDialog(options?: MainThreadDialogSaveOptions): Promise<URI | undefined> {
const convertedOptions = MainThreadDialogs._convertSaveOptions(options);
if (!convertedOptions.defaultUri) {
convertedOptions.defaultUri = await this._fileDialogService.defaultFilePath();
}
return Promise.resolve(this._fileDialogService.showSaveDialog(convertedOptions));
}
private static _convertOpenOptions(options?: MainThreadDialogOpenOptions): IOpenDialogOptions {
@@ -38,7 +46,8 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape {
canSelectFolders: options?.canSelectFolders,
canSelectMany: options?.canSelectMany,
defaultUri: options?.defaultUri ? URI.revive(options.defaultUri) : undefined,
title: options?.title || undefined
title: options?.title || undefined,
availableFileSystems: []
};
if (options?.filters) {
result.filters = [];

View File

@@ -19,9 +19,8 @@ import { MainThreadDocuments } from 'vs/workbench/api/browser/mainThreadDocument
import { MainThreadTextEditor } from 'vs/workbench/api/browser/mainThreadEditor';
import { MainThreadTextEditors } from 'vs/workbench/api/browser/mainThreadEditors';
import { ExtHostContext, ExtHostDocumentsAndEditorsShape, IDocumentsAndEditorsDelta, IExtHostContext, IModelAddedData, ITextEditorAddData, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { EditorViewColumn, editorGroupToViewColumn } from 'vs/workbench/api/common/shared/editor';
import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor';
import { IEditorPane } from 'vs/workbench/common/editor';
import { editorGroupToViewColumn, EditorGroupColumn, IEditorPane } from 'vs/workbench/common/editor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
@@ -31,41 +30,8 @@ import { IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/commo
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { diffSets, diffMaps } from 'vs/base/common/collections';
namespace delta {
export function ofSets<T>(before: Set<T>, after: Set<T>): { removed: T[], added: T[] } {
const removed: T[] = [];
const added: T[] = [];
for (let element of before) {
if (!after.has(element)) {
removed.push(element);
}
}
for (let element of after) {
if (!before.has(element)) {
added.push(element);
}
}
return { removed, added };
}
export function ofMaps<K, V>(before: Map<K, V>, after: Map<K, V>): { removed: V[], added: V[] } {
const removed: V[] = [];
const added: V[] = [];
for (let [index, value] of before) {
if (!after.has(index)) {
removed.push(value);
}
}
for (let [index, value] of after) {
if (!before.has(index)) {
added.push(value);
}
}
return { removed, added };
}
}
class TextEditorSnapshot {
@@ -118,8 +84,8 @@ class DocumentAndEditorState {
undefined, after.activeEditor
);
}
const documentDelta = delta.ofSets(before.documents, after.documents);
const editorDelta = delta.ofMaps(before.textEditors, after.textEditors);
const documentDelta = diffSets(before.documents, after.documents);
const editorDelta = diffMaps(before.textEditors, after.textEditors);
const oldActiveEditor = before.activeEditor !== after.activeEditor ? before.activeEditor : undefined;
const newActiveEditor = before.activeEditor !== after.activeEditor ? after.activeEditor : undefined;
@@ -443,7 +409,7 @@ export class MainThreadDocumentsAndEditors {
};
}
private _findEditorPosition(editor: MainThreadTextEditor): EditorViewColumn | undefined {
private _findEditorPosition(editor: MainThreadTextEditor): EditorGroupColumn | undefined {
for (const editorPane of this._editorService.visibleEditorPanes) {
if (editor.matches(editorPane)) {
return editorGroupToViewColumn(this._editorGroupService, editorPane.group);

View File

@@ -14,18 +14,14 @@ import { ISelection } from 'vs/editor/common/core/selection';
import { IDecorationOptions, IDecorationRenderOptions, ILineChange } from 'vs/editor/common/editorCommon';
import { ISingleEditOperation } from 'vs/editor/common/model';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { IEditorOptions, ITextEditorOptions, IResourceEditorInput, EditorActivation } from 'vs/platform/editor/common/editor';
import { ITextEditorOptions, IResourceEditorInput, EditorActivation } from 'vs/platform/editor/common/editor';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { MainThreadDocumentsAndEditors } from 'vs/workbench/api/browser/mainThreadDocumentsAndEditors';
import { MainThreadTextEditor } from 'vs/workbench/api/browser/mainThreadEditor';
import { ExtHostContext, ExtHostEditorsShape, IApplyEditsOptions, IExtHostContext, ITextDocumentShowOptions, ITextEditorConfigurationUpdate, ITextEditorPositionData, IUndoStopOptions, MainThreadTextEditorsShape, TextEditorRevealType, IWorkspaceEditDto, WorkspaceEditType } from 'vs/workbench/api/common/extHost.protocol';
import { EditorViewColumn, editorGroupToViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
import { editorGroupToViewColumn, EditorGroupColumn, viewColumnToEditorGroup } from 'vs/workbench/common/editor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { openEditorWith } from 'vs/workbench/services/editor/common/editorOpenWith';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { revive } from 'vs/base/common/marshalling';
@@ -161,7 +157,7 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
return this._documentsAndEditors.findTextEditorIdFor(editor);
}
async $tryShowEditor(id: string, position?: EditorViewColumn): Promise<void> {
async $tryShowEditor(id: string, position?: EditorGroupColumn): Promise<void> {
const mainThreadEditor = this._documentsAndEditors.getEditor(id);
if (mainThreadEditor) {
const model = mainThreadEditor.getModel();
@@ -297,59 +293,6 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
// --- commands
CommandsRegistry.registerCommand('_workbench.open', async function (accessor: ServicesAccessor, args: [URI, IEditorOptions, EditorViewColumn, string?]) {
const editorService = accessor.get(IEditorService);
const editorGroupService = accessor.get(IEditorGroupsService);
const openerService = accessor.get(IOpenerService);
const [resource, options, position, label] = args;
if (options || typeof position === 'number') {
// use editor options or editor view column as a hint to use the editor service for opening
await editorService.openEditor({ resource, options, label }, viewColumnToEditorGroup(editorGroupService, position));
return;
}
if (resource && resource.scheme === 'command') {
// do not allow to execute commands from here
return;
}
// finally, delegate to opener service
await openerService.open(resource);
});
CommandsRegistry.registerCommand('_workbench.openWith', (accessor: ServicesAccessor, args: [URI, string, ITextEditorOptions | undefined, EditorViewColumn | undefined]) => {
const editorService = accessor.get(IEditorService);
const editorGroupsService = accessor.get(IEditorGroupsService);
const configurationService = accessor.get(IConfigurationService);
const quickInputService = accessor.get(IQuickInputService);
const [resource, id, options, position] = args;
const group = editorGroupsService.getGroup(viewColumnToEditorGroup(editorGroupsService, position)) ?? editorGroupsService.activeGroup;
const textOptions: ITextEditorOptions = options ? { ...options, override: false } : { override: false };
const input = editorService.createEditorInput({ resource });
return openEditorWith(input, id, textOptions, group, editorService, configurationService, quickInputService);
});
CommandsRegistry.registerCommand('_workbench.diff', async function (accessor: ServicesAccessor, args: [URI, URI, string, string, IEditorOptions, EditorViewColumn]) {
const editorService = accessor.get(IEditorService);
const editorGroupService = accessor.get(IEditorGroupsService);
let [leftResource, rightResource, label, description, options, position] = args;
if (!options || typeof options !== 'object') {
options = {
preserveFocus: false
};
}
await editorService.openEditor({ leftResource, rightResource, label, description, options }, viewColumnToEditorGroup(editorGroupService, position));
});
CommandsRegistry.registerCommand('_workbench.revertAllDirty', async function (accessor: ServicesAccessor) {
const environmentService = accessor.get(IEnvironmentService);
if (!environmentService.extensionTestsLocationURI) {

View File

@@ -54,11 +54,13 @@ export class MainThreadFileSystemEventService {
// BEFORE file operation
workingCopyFileService.addFileOperationParticipant({
participate: (files, operation, progress, timeout, token) => {
return proxy.$onWillRunFileOperation(operation, files, timeout, token);
this._listener.add(workingCopyFileService.addFileOperationParticipant({
participate: async (files, operation, undoRedoGroupId, isUndoing, _progress, timeout, token) => {
if (!isUndoing) {
return proxy.$onWillRunFileOperation(operation, files, undoRedoGroupId, timeout, token);
}
}
});
}));
// AFTER file operation
this._listener.add(workingCopyFileService.onDidRunWorkingCopyFileOperation(e => proxy.$onDidRunFileOperation(e.operation, e.files)));
@@ -75,7 +77,7 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat
properties: {
'files.participants.timeout': {
type: 'number',
default: 5000,
default: 60000,
markdownDescription: localize('files.participants.timeout', "Timeout in milliseconds after which file participants for create, rename, and delete are cancelled. Use `0` to disable participants."),
}
}

View File

@@ -165,16 +165,15 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
$registerCodeLensSupport(handle: number, selector: IDocumentFilterDto[], eventHandle: number | undefined): void {
const provider = <modes.CodeLensProvider>{
provideCodeLenses: (model: ITextModel, token: CancellationToken): Promise<modes.CodeLensList | undefined> => {
return this._proxy.$provideCodeLenses(handle, model.uri, token).then(listDto => {
if (!listDto) {
return undefined;
}
return {
lenses: listDto.lenses,
dispose: () => listDto.cacheId && this._proxy.$releaseCodeLenses(handle, listDto.cacheId)
};
});
provideCodeLenses: async (model: ITextModel, token: CancellationToken): Promise<modes.CodeLensList | undefined> => {
const listDto = await this._proxy.$provideCodeLenses(handle, model.uri, token);
if (!listDto) {
return undefined;
}
return {
lenses: listDto.lenses,
dispose: () => listDto.cacheId && this._proxy.$releaseCodeLenses(handle, listDto.cacheId)
};
},
resolveCodeLens: (_model: ITextModel, codeLens: modes.CodeLens, token: CancellationToken): Promise<modes.CodeLens | undefined> => {
return this._proxy.$resolveCodeLens(handle, codeLens, token);
@@ -261,14 +260,12 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
}));
}
// --- on type rename
// --- linked editing
$registerOnTypeRenameProvider(handle: number, selector: IDocumentFilterDto[], wordPattern?: IRegExpDto): void {
const revivedWordPattern = wordPattern ? MainThreadLanguageFeatures._reviveRegExp(wordPattern) : undefined;
this._registrations.set(handle, modes.OnTypeRenameProviderRegistry.register(selector, <modes.OnTypeRenameProvider>{
wordPattern: revivedWordPattern,
provideOnTypeRenameRanges: async (model: ITextModel, position: EditorPosition, token: CancellationToken): Promise<{ ranges: IRange[]; wordPattern?: RegExp; } | undefined> => {
const res = await this._proxy.$provideOnTypeRenameRanges(handle, model.uri, position, token);
$registerLinkedEditingRangeProvider(handle: number, selector: IDocumentFilterDto[]): void {
this._registrations.set(handle, modes.LinkedEditingRangeProviderRegistry.register(selector, <modes.LinkedEditingRangeProvider>{
provideLinkedEditingRanges: async (model: ITextModel, position: EditorPosition, token: CancellationToken): Promise<modes.LinkedEditingRanges | undefined> => {
const res = await this._proxy.$provideLinkedEditingRanges(handle, model.uri, position, token);
if (res) {
return {
ranges: res.ranges,

View File

@@ -5,6 +5,7 @@
import * as DOM from 'vs/base/browser/dom';
import { CancellationToken } from 'vs/base/common/cancellation';
import { diffMaps, diffSets } from 'vs/base/common/collections';
import { Emitter } from 'vs/base/common/event';
import { IRelativePattern } from 'vs/base/common/glob';
import { combinedDisposable, Disposable, DisposableStore, dispose, IDisposable, IReference } from 'vs/base/common/lifecycle';
@@ -14,8 +15,11 @@ import { IExtUri } from 'vs/base/common/resources';
import { URI, UriComponents } from 'vs/base/common/uri';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { EditorActivation, ITextEditorOptions } from 'vs/platform/editor/common/editor';
import { ILogService } from 'vs/platform/log/common/log';
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { viewColumnToEditorGroup } from 'vs/workbench/common/editor';
import { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
@@ -23,44 +27,14 @@ import { INotebookCellStatusBarService } from 'vs/workbench/contrib/notebook/com
import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, CellEditType, DisplayOrderKey, ICellEditOperation, ICellRange, IEditor, IMainCellDto, INotebookDecorationRenderOptions, INotebookDocumentFilter, INotebookEditorModel, INotebookExclusiveDocumentFilter, NotebookCellOutputsSplice, NotebookCellsChangeType, NOTEBOOK_DISPLAY_ORDER, TransientMetadata } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
import { IMainNotebookController, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroup, IEditorGroupsService, preferredSideBySideGroupDirection } from 'vs/workbench/services/editor/common/editorGroupsService';
import { openEditorWith } from 'vs/workbench/services/editor/common/editorOpenWith';
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, INotebookCellStatusBarEntryDto, INotebookDocumentsAndEditorsDelta, INotebookModelAddedData, MainContext, MainThreadNotebookShape, NotebookEditorRevealType, NotebookExtensionDescription } from '../common/extHost.protocol';
import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, INotebookCellStatusBarEntryDto, INotebookDocumentsAndEditorsDelta, INotebookDocumentShowOptions, INotebookModelAddedData, MainContext, MainThreadNotebookShape, NotebookEditorRevealType, NotebookExtensionDescription } from '../common/extHost.protocol';
class DocumentAndEditorState {
static ofSets<T>(before: Set<T>, after: Set<T>): { removed: T[], added: T[] } {
const removed: T[] = [];
const added: T[] = [];
before.forEach(element => {
if (!after.has(element)) {
removed.push(element);
}
});
after.forEach(element => {
if (!before.has(element)) {
added.push(element);
}
});
return { removed, added };
}
static ofMaps<K, V>(before: Map<K, V>, after: Map<K, V>): { removed: V[], added: V[] } {
const removed: V[] = [];
const added: V[] = [];
before.forEach((value, index) => {
if (!after.has(index)) {
removed.push(value);
}
});
after.forEach((value, index) => {
if (!before.has(index)) {
added.push(value);
}
});
return { removed, added };
}
static compute(before: DocumentAndEditorState | undefined, after: DocumentAndEditorState): INotebookDocumentsAndEditorsDelta {
if (!before) {
const apiEditors = [];
@@ -75,8 +49,8 @@ class DocumentAndEditorState {
visibleEditors: [...after.visibleEditors].map(editor => editor[0])
};
}
const documentDelta = DocumentAndEditorState.ofSets(before.documents, after.documents);
const editorDelta = DocumentAndEditorState.ofMaps(before.textEditors, after.textEditors);
const documentDelta = diffSets(before.documents, after.documents);
const editorDelta = diffMaps(before.textEditors, after.textEditors);
const addedAPIEditors = editorDelta.added.map(add => ({
id: add.getId(),
documentUri: add.uri!,
@@ -89,7 +63,7 @@ class DocumentAndEditorState {
// const oldActiveEditor = before.activeEditor !== after.activeEditor ? before.activeEditor : undefined;
const newActiveEditor = before.activeEditor !== after.activeEditor ? after.activeEditor : undefined;
const visibleEditorDelta = DocumentAndEditorState.ofMaps(before.visibleEditors, after.visibleEditors);
const visibleEditorDelta = diffMaps(before.visibleEditors, after.visibleEditors);
return {
addedDocuments: documentDelta.added.map((e: NotebookTextModel): INotebookModelAddedData => {
@@ -152,7 +126,10 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
@INotebookService private _notebookService: INotebookService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IEditorService private readonly editorService: IEditorService,
@IEditorGroupsService private readonly editorGroupsService: IEditorGroupsService,
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
@IQuickInputService private readonly quickInputService: IQuickInputService,
@ILogService private readonly logService: ILogService,
@INotebookCellStatusBarService private readonly cellStatusBarService: INotebookCellStatusBarService,
@IWorkingCopyService private readonly _workingCopyService: IWorkingCopyService,
@@ -171,7 +148,6 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
if (!textModel) {
return false;
}
this._notebookService.transformEditsOutputs(textModel, cellEdits);
return textModel.applyEdits(modelVersionId, cellEdits, true, undefined, () => undefined, undefined);
}
@@ -413,9 +389,9 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
const editors = new Map<string, IEditor>();
this._notebookService.listNotebookEditors().forEach(editor => {
if (editor.hasModel()) {
if (editor.textModel) {
editors.set(editor.getId(), editor);
documentEditorsMap.set(editor.textModel!.uri.toString(), editor);
documentEditorsMap.set(editor.textModel.uri.toString(), editor);
}
});
@@ -434,7 +410,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
documents.add(document);
});
if (!activeEditor && focusedNotebookEditor && focusedNotebookEditor.hasModel()) {
if (!activeEditor && focusedNotebookEditor && focusedNotebookEditor.textModel) {
activeEditor = focusedNotebookEditor.getId();
}
@@ -479,8 +455,6 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
const edits: ICellEditOperation[] = [
{ editType: CellEditType.Replace, index: 0, count: mainthreadTextModel.cells.length, cells: data.cells }
];
this._notebookService.transformEditsOutputs(mainthreadTextModel, edits);
await new Promise(resolve => {
DOM.scheduleAtNextAnimationFrame(() => {
const ret = mainthreadTextModel!.applyEdits(mainthreadTextModel!.versionId, edits, true, undefined, () => undefined, undefined);
@@ -606,7 +580,6 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
return;
}
this._notebookService.transformSpliceOutputs(textModel, splices);
const cell = textModel.cells.find(cell => cell.handle === cellHandle);
if (!cell) {
@@ -662,8 +635,11 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
const editor = this._notebookService.listNotebookEditors().find(editor => editor.getId() === id);
if (editor && editor.isNotebookEditor) {
const notebookEditor = editor as INotebookEditor;
if (!notebookEditor.hasModel()) {
return;
}
const viewModel = notebookEditor.viewModel;
const cell = viewModel?.viewCells[range.start];
const cell = viewModel.viewCells[range.start];
if (!cell) {
return;
}
@@ -726,6 +702,51 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
return uri;
}
async $tryShowNotebookDocument(resource: UriComponents, viewType: string, options: INotebookDocumentShowOptions): Promise<string> {
const editorOptions: ITextEditorOptions = {
preserveFocus: options.preserveFocus,
pinned: options.pinned,
// selection: options.selection,
// preserve pre 1.38 behaviour to not make group active when preserveFocus: true
// but make sure to restore the editor to fix https://github.com/microsoft/vscode/issues/79633
activation: options.preserveFocus ? EditorActivation.RESTORE : undefined,
override: false,
};
const columnArg = viewColumnToEditorGroup(this._editorGroupService, options.position);
let group: IEditorGroup | undefined = undefined;
if (columnArg === SIDE_GROUP) {
const direction = preferredSideBySideGroupDirection(this.configurationService);
let neighbourGroup = this.editorGroupsService.findGroup({ direction });
if (!neighbourGroup) {
neighbourGroup = this.editorGroupsService.addGroup(this.editorGroupsService.activeGroup, direction);
}
group = neighbourGroup;
} else {
group = this.editorGroupsService.getGroup(viewColumnToEditorGroup(this.editorGroupsService, columnArg)) ?? this.editorGroupsService.activeGroup;
}
const input = this.editorService.createEditorInput({ resource: URI.revive(resource), options: editorOptions });
// TODO: handle options.selection
const editorPane = await openEditorWith(input, viewType, options, group, this.editorService, this.configurationService, this.quickInputService);
const notebookEditor = (editorPane as unknown as { isNotebookEditor?: boolean })?.isNotebookEditor ? (editorPane!.getControl() as INotebookEditor) : undefined;
if (notebookEditor) {
if (notebookEditor.viewModel && options.selection && notebookEditor.viewModel.viewCells[options.selection.start]) {
const focusedCell = notebookEditor.viewModel.viewCells[options.selection.start];
notebookEditor.revealInCenterIfOutsideViewport(focusedCell);
notebookEditor.selectElement(focusedCell);
}
return notebookEditor.getId();
} else {
throw new Error(`Notebook Editor creation failure for documenet ${resource}`);
}
}
}

View File

@@ -68,7 +68,8 @@ class MainThreadSCMResource implements ISCMResource {
readonly sourceUri: URI,
readonly resourceGroup: ISCMResourceGroup,
readonly decorations: ISCMResourceDecorations,
readonly contextValue: string | undefined
readonly contextValue: string | undefined,
readonly command: Command | undefined
) { }
open(preserveFocus: boolean): Promise<void> {
@@ -201,7 +202,7 @@ class MainThreadSCMProvider implements ISCMProvider {
for (const [start, deleteCount, rawResources] of groupSlices) {
const resources = rawResources.map(rawResource => {
const [handle, sourceUri, icons, tooltip, strikeThrough, faded, contextValue] = rawResource;
const [handle, sourceUri, icons, tooltip, strikeThrough, faded, contextValue, command] = rawResource;
const icon = icons[0];
const iconDark = icons[1] || icon;
const decorations = {
@@ -220,7 +221,8 @@ class MainThreadSCMProvider implements ISCMProvider {
URI.revive(sourceUri),
group,
decorations,
contextValue || undefined
contextValue || undefined,
command
);
});

View File

@@ -27,7 +27,7 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape {
this.entries.clear();
}
$setEntry(id: number, statusId: string, statusName: string, text: string, tooltip: string | undefined, command: Command | undefined, color: string | ThemeColor | undefined, alignment: MainThreadStatusBarAlignment, priority: number | undefined, accessibilityInformation: IAccessibilityInformation): void {
$setEntry(id: number, statusId: string, statusName: string, text: string, tooltip: string | undefined, command: Command | undefined, color: string | ThemeColor | undefined, backgroundColor: string | ThemeColor | undefined, alignment: MainThreadStatusBarAlignment, priority: number | undefined, accessibilityInformation: IAccessibilityInformation): void {
// if there are icons in the text use the tooltip for the aria label
let ariaLabel: string;
let role: string | undefined = undefined;
@@ -37,7 +37,7 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape {
} else {
ariaLabel = text ? text.replace(MainThreadStatusBar.CODICON_REGEXP, (_match, codiconName) => codiconName) : '';
}
const entry: IStatusbarEntry = { text, tooltip, command, color, ariaLabel, role };
const entry: IStatusbarEntry = { text, tooltip, command, color, backgroundColor, ariaLabel, role };
if (typeof priority === 'undefined') {
priority = 0;

View File

@@ -3,17 +3,17 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { MainThreadStorageShape, MainContext, IExtHostContext, ExtHostStorageShape, ExtHostContext } from '../common/extHost.protocol';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IExtensionIdWithVersion, IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { IExtensionIdWithVersion, IExtensionsStorageSyncService } from 'vs/platform/userDataSync/common/extensionsStorageSync';
@extHostNamedCustomer(MainContext.MainThreadStorage)
export class MainThreadStorage implements MainThreadStorageShape {
private readonly _storageService: IStorageService;
private readonly _storageKeysSyncRegistryService: IStorageKeysSyncRegistryService;
private readonly _extensionsStorageSyncService: IExtensionsStorageSyncService;
private readonly _proxy: ExtHostStorageShape;
private readonly _storageListener: IDisposable;
private readonly _sharedStorageKeysToWatch: Map<string, boolean> = new Map<string, boolean>();
@@ -21,13 +21,13 @@ export class MainThreadStorage implements MainThreadStorageShape {
constructor(
extHostContext: IExtHostContext,
@IStorageService storageService: IStorageService,
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService,
@IExtensionsStorageSyncService extensionsStorageSyncService: IExtensionsStorageSyncService,
) {
this._storageService = storageService;
this._storageKeysSyncRegistryService = storageKeysSyncRegistryService;
this._extensionsStorageSyncService = extensionsStorageSyncService;
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostStorage);
this._storageListener = this._storageService.onDidChangeStorage(e => {
this._storageListener = this._storageService.onDidChangeValue(e => {
const shared = e.scope === StorageScope.GLOBAL;
if (shared && this._sharedStorageKeysToWatch.has(e.key)) {
try {
@@ -66,7 +66,12 @@ export class MainThreadStorage implements MainThreadStorageShape {
let jsonValue: string;
try {
jsonValue = JSON.stringify(value);
<<<<<<< HEAD
await this._storageService.store(key, jsonValue, shared ? StorageScope.GLOBAL : StorageScope.WORKSPACE);
=======
// Extension state is synced separately through extensions
this._storageService.store(key, jsonValue, shared ? StorageScope.GLOBAL : StorageScope.WORKSPACE, StorageTarget.MACHINE);
>>>>>>> e4a830e9b7ca039c7c70697786d29f5b6679d775
} catch (err) {
return Promise.reject(err);
}
@@ -74,6 +79,6 @@ export class MainThreadStorage implements MainThreadStorageShape {
}
$registerExtensionStorageKeysToSync(extension: IExtensionIdWithVersion, keys: string[]): void {
this._storageKeysSyncRegistryService.registerExtensionStorageKeys(extension, keys);
this._extensionsStorageSyncService.setKeysForSync(extension, keys);
}
}

View File

@@ -53,7 +53,7 @@ namespace TaskProcessStartedDTO {
}
namespace TaskProcessEndedDTO {
export function from(value: TaskExecution, exitCode: number): TaskProcessEndedDTO {
export function from(value: TaskExecution, exitCode: number | undefined): TaskProcessEndedDTO {
return {
id: value.id,
exitCode
@@ -429,7 +429,7 @@ export class MainThreadTask implements MainThreadTaskShape {
} else if (event.kind === TaskEventKind.ProcessStarted) {
this._proxy.$onDidStartTaskProcess(TaskProcessStartedDTO.from(task.getTaskExecution(), event.processId!));
} else if (event.kind === TaskEventKind.ProcessEnded) {
this._proxy.$onDidEndTaskProcess(TaskProcessEndedDTO.from(task.getTaskExecution(), event.exitCode!));
this._proxy.$onDidEndTaskProcess(TaskProcessEndedDTO.from(task.getTaskExecution(), event.exitCode));
} else if (event.kind === TaskEventKind.End) {
this._proxy.$OnDidEndTask(TaskExecutionDTO.from(task.getTaskExecution()));
}

View File

@@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { getTestSubscriptionKey, RunTestsRequest, RunTestsResult, TestsDiff } from 'vs/workbench/contrib/testing/common/testCollection';
import { ITestService } from 'vs/workbench/contrib/testing/common/testService';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { ExtHostContext, ExtHostTestingResource, ExtHostTestingShape, IExtHostContext, MainContext, MainThreadTestingShape } from '../common/extHost.protocol';
import { URI, UriComponents } from 'vs/base/common/uri';
@extHostNamedCustomer(MainContext.MainThreadTesting)
export class MainThreadTesting extends Disposable implements MainThreadTestingShape {
private readonly proxy: ExtHostTestingShape;
private readonly testSubscriptions = new Map<string, IDisposable>();
constructor(
extHostContext: IExtHostContext,
@ITestService private readonly testService: ITestService,
) {
super();
this.proxy = extHostContext.getProxy(ExtHostContext.ExtHostTesting);
this._register(this.testService.onShouldSubscribe(args => this.proxy.$subscribeToTests(args.resource, args.uri)));
this._register(this.testService.onShouldUnsubscribe(args => this.proxy.$unsubscribeFromTests(args.resource, args.uri)));
}
/**
* @inheritdoc
*/
public $registerTestProvider(id: string) {
this.testService.registerTestController(id, {
runTests: req => this.proxy.$runTestsForProvider(req),
});
}
/**
* @inheritdoc
*/
public $unregisterTestProvider(id: string) {
this.testService.unregisterTestController(id);
}
/**
* @inheritdoc
*/
$subscribeToDiffs(resource: ExtHostTestingResource, uriComponents: UriComponents): void {
const uri = URI.revive(uriComponents);
const disposable = this.testService.subscribeToDiffs(resource, uri,
diff => this.proxy.$acceptDiff(resource, uriComponents, diff));
this.testSubscriptions.set(getTestSubscriptionKey(resource, uri), disposable);
}
/**
* @inheritdoc
*/
public $unsubscribeFromDiffs(resource: ExtHostTestingResource, uriComponents: UriComponents): void {
const key = getTestSubscriptionKey(resource, URI.revive(uriComponents));
this.testSubscriptions.get(key)?.dispose();
this.testSubscriptions.delete(key);
}
/**
* @inheritdoc
*/
public $publishDiff(resource: ExtHostTestingResource, uri: UriComponents, diff: TestsDiff): void {
this.testService.publishDiff(resource, URI.revive(uri), diff);
}
public $runTests(req: RunTestsRequest): Promise<RunTestsResult> {
return this.testService.runTests(req);
}
public dispose() {
// no-op
}
}

View File

@@ -52,14 +52,14 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
});
}
$reveal(treeViewId: string, item: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise<void> {
this.logService.trace('MainThreadTreeViews#$reveal', treeViewId, item, parentChain, options);
$reveal(treeViewId: string, itemInfo: { item: ITreeItem, parentChain: ITreeItem[] } | undefined, options: IRevealOptions): Promise<void> {
this.logService.trace('MainThreadTreeViews#$reveal', treeViewId, itemInfo?.item, itemInfo?.parentChain, options);
return this.viewsService.openView(treeViewId, options.focus)
.then(() => {
const viewer = this.getTreeView(treeViewId);
if (viewer) {
return this.reveal(viewer, this._dataProviders.get(treeViewId)!, item, parentChain, options);
if (viewer && itemInfo) {
return this.reveal(viewer, this._dataProviders.get(treeViewId)!, itemInfo.item, itemInfo.parentChain, options);
}
return undefined;
});
@@ -235,10 +235,14 @@ class TreeViewDataProvider implements ITreeViewDataProvider {
private updateTreeItem(current: ITreeItem, treeItem: ITreeItem): void {
treeItem.children = treeItem.children ? treeItem.children : undefined;
if (current) {
const properties = distinct([...Object.keys(current), ...Object.keys(treeItem)]);
const properties = distinct([...Object.keys(current instanceof ResolvableTreeItem ? current.asTreeItem() : current),
...Object.keys(treeItem)]);
for (const property of properties) {
(<any>current)[property] = (<any>treeItem)[property];
}
if (current instanceof ResolvableTreeItem) {
current.resetResolve();
}
}
}
}

View File

@@ -6,8 +6,8 @@
import { MainThreadTunnelServiceShape, IExtHostContext, MainContext, ExtHostContext, ExtHostTunnelServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { IRemoteExplorerService, MakeAddress } from 'vs/workbench/services/remote/common/remoteExplorerService';
import { ITunnelProvider, ITunnelService, TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { IRemoteExplorerService, makeAddress } from 'vs/workbench/services/remote/common/remoteExplorerService';
import { ITunnelProvider, ITunnelService, TunnelCreationOptions, TunnelOptions } from 'vs/platform/remote/common/tunnel';
import { Disposable } from 'vs/base/common/lifecycle';
import type { TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver';
@@ -26,8 +26,8 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
this._register(tunnelService.onTunnelClosed(() => this._proxy.$onDidTunnelsChange()));
}
async $openTunnel(tunnelOptions: TunnelOptions): Promise<TunnelDto | undefined> {
const tunnel = await this.remoteExplorerService.forward(tunnelOptions.remoteAddress, tunnelOptions.localAddressPort, tunnelOptions.label);
async $openTunnel(tunnelOptions: TunnelOptions, source: string): Promise<TunnelDto | undefined> {
const tunnel = await this.remoteExplorerService.forward(tunnelOptions.remoteAddress, tunnelOptions.localAddressPort, tunnelOptions.label, source);
if (tunnel) {
return TunnelDto.fromServiceTunnel(tunnel);
}
@@ -47,8 +47,8 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
});
}
async $registerCandidateFinder(): Promise<void> {
this.remoteExplorerService.registerCandidateFinder(() => this._proxy.$findCandidatePorts());
async $onFoundNewCandidates(candidates: { host: string, port: number, detail: string }[]): Promise<void> {
this.remoteExplorerService.onFoundNewCandidates(candidates);
}
async $tunnelServiceReady(): Promise<void> {
@@ -57,19 +57,17 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
async $setTunnelProvider(): Promise<void> {
const tunnelProvider: ITunnelProvider = {
forwardPort: (tunnelOptions: TunnelOptions) => {
const forward = this._proxy.$forwardPort(tunnelOptions);
forwardPort: (tunnelOptions: TunnelOptions, tunnelCreationOptions: TunnelCreationOptions) => {
const forward = this._proxy.$forwardPort(tunnelOptions, tunnelCreationOptions);
if (forward) {
return forward.then(tunnel => {
return {
tunnelRemotePort: tunnel.remoteAddress.port,
tunnelRemoteHost: tunnel.remoteAddress.host,
localAddress: typeof tunnel.localAddress === 'string' ? tunnel.localAddress : MakeAddress(tunnel.localAddress.host, tunnel.localAddress.port),
localAddress: typeof tunnel.localAddress === 'string' ? tunnel.localAddress : makeAddress(tunnel.localAddress.host, tunnel.localAddress.port),
tunnelLocalPort: typeof tunnel.localAddress !== 'string' ? tunnel.localAddress.port : undefined,
dispose: (silent: boolean) => {
if (!silent) {
this._proxy.$closeTunnel({ host: tunnel.remoteAddress.host, port: tunnel.remoteAddress.port });
}
dispose: (silent?: boolean) => {
this._proxy.$closeTunnel({ host: tunnel.remoteAddress.host, port: tunnel.remoteAddress.port }, silent);
}
};
});
@@ -80,22 +78,6 @@ export class MainThreadTunnelService extends Disposable implements MainThreadTun
this.tunnelService.setTunnelProvider(tunnelProvider);
}
async $setCandidateFilter(): Promise<void> {
this._register(this.remoteExplorerService.setCandidateFilter(async (candidates: { host: string, port: number, detail: string }[]): Promise<{ host: string, port: number, detail: string }[]> => {
const filters: boolean[] = await this._proxy.$filterCandidates(candidates);
const filteredCandidates: { host: string, port: number, detail: string }[] = [];
if (filters.length !== candidates.length) {
return candidates;
}
for (let i = 0; i < candidates.length; i++) {
if (filters[i]) {
filteredCandidates.push(candidates[i]);
}
}
return filteredCandidates;
}));
}
dispose(): void {
}

View File

@@ -9,8 +9,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { MainThreadWebviews, reviveWebviewExtension, reviveWebviewOptions } from 'vs/workbench/api/browser/mainThreadWebviews';
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
import { IEditorInput } from 'vs/workbench/common/editor';
import { editorGroupToViewColumn, EditorGroupColumn, IEditorInput, viewColumnToEditorGroup } from 'vs/workbench/common/editor';
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { WebviewIcons } from 'vs/workbench/contrib/webview/browser/webview';
import { WebviewInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditorInput';
@@ -150,7 +149,7 @@ export class MainThreadWebviewPanels extends Disposable implements extHostProtoc
handle: extHostProtocol.WebviewHandle,
viewType: string,
title: string,
showOptions: { viewColumn?: EditorViewColumn, preserveFocus?: boolean; },
showOptions: { viewColumn?: EditorGroupColumn, preserveFocus?: boolean; },
options: WebviewInputOptions
): void {
const mainThreadShowOptions: ICreateWebViewShowOptions = Object.create(null);

View File

@@ -8,8 +8,8 @@ import { forEach } from 'vs/base/common/collections';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import * as resources from 'vs/base/common/resources';
import { ExtensionMessageCollector, ExtensionsRegistry, IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { ViewContainer, IViewsRegistry, ITreeViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions, TEST_VIEW_CONTAINER_ID, IViewDescriptor, ViewContainerLocation } from 'vs/workbench/common/views';
import { TreeViewPane } from 'vs/workbench/browser/parts/views/treeView';
import { ViewContainer, IViewsRegistry, ITreeViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions, TEST_VIEW_CONTAINER_ID, IViewDescriptor, ViewContainerLocation, testViewIcon } from 'vs/workbench/common/views';
import { CustomTreeView, TreeViewPane } from 'vs/workbench/browser/parts/views/treeView';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { coalesce, } from 'vs/base/common/arrays';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
@@ -30,9 +30,8 @@ import { IWorkbenchActionRegistry, Extensions as ActionExtensions, CATEGORIES }
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { Codicon } from 'vs/base/common/codicons';
import { CustomTreeView } from 'vs/workbench/contrib/views/browser/treeView';
import { WebviewViewPane } from 'vs/workbench/contrib/webviewView/browser/webviewViewPane';
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
export interface IUserFriendlyViewsContainerDescriptor {
id: string;
@@ -321,7 +320,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
private registerTestViewContainer(): void {
const title = localize('test', "Test");
const icon = Codicon.beaker.classNames;
const icon = testViewIcon;
this.registerCustomViewContainer(TEST_VIEW_CONTAINER_ID, title, icon, TEST_VIEW_CONTAINER_ORDER, undefined, ViewContainerLocation.Sidebar);
}
@@ -356,7 +355,9 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
private registerCustomViewContainers(containers: IUserFriendlyViewsContainerDescriptor[], extension: IExtensionDescription, order: number, existingViewContainers: ViewContainer[], location: ViewContainerLocation): number {
containers.forEach(descriptor => {
const icon = resources.joinPath(extension.extensionLocation, descriptor.icon);
const themeIcon = ThemeIcon.fromString(descriptor.icon);
const icon = themeIcon || resources.joinPath(extension.extensionLocation, descriptor.icon);
const id = `workbench.view.extension.${descriptor.id}`;
const viewContainer = this.registerCustomViewContainer(id, descriptor.title, icon, order++, extension.identifier, location);
@@ -376,7 +377,7 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
return order;
}
private registerCustomViewContainer(id: string, title: string, icon: URI | string, order: number, extensionId: ExtensionIdentifier | undefined, location: ViewContainerLocation): ViewContainer {
private registerCustomViewContainer(id: string, title: string, icon: URI | ThemeIcon, order: number, extensionId: ExtensionIdentifier | undefined, location: ViewContainerLocation): ViewContainer {
let viewContainer = this.viewContainersRegistry.get(id);
if (!viewContainer) {
@@ -470,7 +471,11 @@ class ViewsExtensionHandler implements IWorkbenchContribution {
? container.viewOrderDelegate.getOrder(item.group)
: undefined;
const icon = item.icon ? resources.joinPath(extension.description.extensionLocation, item.icon) : undefined;
let icon: ThemeIcon | URI | undefined;
if (typeof item.icon === 'string') {
icon = ThemeIcon.fromString(item.icon) || resources.joinPath(extension.description.extensionLocation, item.icon);
}
const initialVisibility = this.convertInitialVisibility(item.visibility);
const type = this.getViewType(item.type);