Merge from vscode 8b5ebbb1b8f6b2127bbbd551ac10cc080482d5b4 (#5041)

This commit is contained in:
Anthony Dresser
2019-04-15 20:37:22 -07:00
committed by GitHub
parent dcdbc95ae7
commit a5bc65fbfb
48 changed files with 495 additions and 294 deletions

View File

@@ -72,8 +72,8 @@ export class FileDialogService implements IFileDialogService {
}
}
// ...then fallback to default folder path
return this.defaultFolderPath(schemeFilter);
// ...then fallback to default file path
return this.defaultFilePath(schemeFilter);
}
private toNativeOpenDialogOptions(options: IPickAndOpenOptions): INativeOpenDialogOptions {

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="-2 -2 16 16" enable-background="new -2 -2 16 16"><polygon fill="#C5C5C5" points="9,0 4.5,9 3,6 0,6 3,12 6,12 12,0"/></svg>

Before

Width:  |  Height:  |  Size: 194 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-fg{fill:#F0EFF1;} .icon-folder{fill:#656565;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M16 2.5v10c0 .827-.673 1.5-1.5 1.5h-11.996c-.827 0-1.5-.673-1.5-1.5v-8c0-.827.673-1.5 1.5-1.5h2.886l1-2h8.11c.827 0 1.5.673 1.5 1.5z" id="outline"/><path class="icon-folder" d="M14.5 2h-7.492l-1 2h-3.504c-.277 0-.5.224-.5.5v8c0 .276.223.5.5.5h11.996c.275 0 .5-.224.5-.5v-10c0-.276-.225-.5-.5-.5zm-.496 2h-6.496l.5-1h5.996v1z" id="iconBg"/><path class="icon-vs-fg" d="M14 3v1h-6.5l.5-1h6z" id="iconFg"/></svg>

Before

Width:  |  Height:  |  Size: 750 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon points="5.382,13 2.382,7 6.618,7 7,7.764 9.382,3 13.618,3 8.618,13" fill="#F6F6F6"/><path d="M12 4l-4 8h-2l-2-4h2l1 2 3-6h2z" fill="#424242"/></svg>

Before

Width:  |  Height:  |  Size: 221 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-fg{opacity:0;fill:#F0EFF1;} .icon-folder{fill:#C5C5C5;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M16 2.5v10c0 .827-.673 1.5-1.5 1.5h-11.996c-.827 0-1.5-.673-1.5-1.5v-8c0-.827.673-1.5 1.5-1.5h2.886l1-2h8.11c.827 0 1.5.673 1.5 1.5z" id="outline"/><path class="icon-folder" d="M14.5 2h-7.492l-1 2h-3.504c-.277 0-.5.224-.5.5v8c0 .276.223.5.5.5h11.996c.275 0 .5-.224.5-.5v-10c0-.276-.225-.5-.5-.5zm-.496 2h-6.496l.5-1h5.996v1z" id="iconBg"/><path class="icon-vs-fg" d="M14 3v1h-6.5l.5-1h6z" id="iconFg"/></svg>

Before

Width:  |  Height:  |  Size: 760 B

View File

@@ -7,7 +7,7 @@ import * as nls from 'vs/nls';
import * as resources from 'vs/base/common/resources';
import * as objects from 'vs/base/common/objects';
import { IFileService, IFileStat, FileKind } from 'vs/platform/files/common/files';
import { IQuickInputService, IQuickPickItem, IQuickPick, IQuickInputButton } from 'vs/platform/quickinput/common/quickInput';
import { IQuickInputService, IQuickPickItem, IQuickPick } from 'vs/platform/quickinput/common/quickInput';
import { URI } from 'vs/base/common/uri';
import { isWindows } from 'vs/base/common/platform';
import { ISaveDialogOptions, IOpenDialogOptions, IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
@@ -23,20 +23,26 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { RemoteFileDialogContext } from 'vs/workbench/common/contextkeys';
import { equalsIgnoreCase } from 'vs/base/common/strings';
import { equalsIgnoreCase, format } from 'vs/base/common/strings';
import { OpenLocalFileAction, OpenLocalFileFolderAction, OpenLocalFolderAction } from 'vs/workbench/browser/actions/workspaceActions';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
interface FileQuickPickItem extends IQuickPickItem {
uri: URI;
isFolder: boolean;
}
enum UpdateResult {
Updated,
NotUpdated,
InvalidPath
}
// Reference: https://en.wikipedia.org/wiki/Filename
const INVALID_FILE_CHARS = isWindows ? /[\\/:\*\?"<>\|]/g : /[\\/]/g;
const WINDOWS_FORBIDDEN_NAMES = /^(con|prn|aux|clock\$|nul|lpt[0-9]|com[0-9])$/i;
export class RemoteFileDialog {
private acceptButton: IQuickInputButton;
private fallbackListItem: FileQuickPickItem | undefined;
private options: IOpenDialogOptions;
private currentFolder: URI;
private filePickBox: IQuickPick<FileQuickPickItem>;
@@ -52,6 +58,7 @@ export class RemoteFileDialog {
private autoCompletePathSegment: string;
private activeItem: FileQuickPickItem;
private userHome: URI;
private badPath: string | undefined;
constructor(
@IFileService private readonly fileService: IFileService,
@@ -64,8 +71,8 @@ export class RemoteFileDialog {
@IModeService private readonly modeService: IModeService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
@IContextKeyService contextKeyService: IContextKeyService
@IKeybindingService private readonly keybindingService: IKeybindingService,
@IContextKeyService contextKeyService: IContextKeyService,
) {
this.remoteAuthority = this.environmentService.configuration.remoteAuthority;
this.contextKey = RemoteFileDialogContext.bindTo(contextKeyService);
@@ -79,13 +86,6 @@ export class RemoteFileDialog {
return Promise.resolve(undefined);
}
this.options = newOptions;
const openFileString = nls.localize('remoteFileDialog.localFileFallback', '(Open Local File)');
const openFolderString = nls.localize('remoteFileDialog.localFolderFallback', '(Open Local Folder)');
const openFileFolderString = nls.localize('remoteFileDialog.localFileFolderFallback', '(Open Local File or Folder)');
let fallbackLabel = options.canSelectFiles ? (options.canSelectFolders ? openFileFolderString : openFileString) : openFolderString;
this.fallbackListItem = this.getFallbackFileSystem(fallbackLabel);
return this.pickResource();
}
@@ -100,7 +100,6 @@ export class RemoteFileDialog {
this.options = newOptions;
this.options.canSelectFolders = true;
this.options.canSelectFiles = true;
this.fallbackListItem = this.getFallbackFileSystem(nls.localize('remoteFileDialog.localSaveFallback', '(Save Local File)'));
return new Promise<URI | undefined>((resolve) => {
this.pickResource(true).then(folderUri => {
@@ -129,20 +128,13 @@ export class RemoteFileDialog {
private remoteUriFrom(path: string): URI {
path = path.replace(/\\/g, '/');
return resources.toLocalResource(URI.from({ scheme: this.scheme, path }), this.remoteAuthority);
return resources.toLocalResource(URI.from({ scheme: this.scheme, path }), this.scheme === Schemas.file ? undefined : this.remoteAuthority);
}
private getScheme(defaultUri: URI | undefined, available: string[] | undefined): string {
return defaultUri ? defaultUri.scheme : (available ? available[0] : Schemas.file);
}
private getFallbackFileSystem(label: string): FileQuickPickItem | undefined {
if (this.options && this.options.availableFileSystems && (this.options.availableFileSystems.length > 1)) {
return { label: label, uri: URI.from({ scheme: this.options.availableFileSystems[1] }), isFolder: true };
}
return undefined;
}
private async getUserHome(): Promise<URI> {
if (this.scheme !== Schemas.file) {
const env = await this.remoteAgentService.getEnvironment();
@@ -182,33 +174,34 @@ export class RemoteFileDialog {
}
}
}
this.acceptButton = { iconPath: this.getDialogIcons('accept'), tooltip: this.options.title };
return new Promise<URI | undefined>(async (resolve) => {
this.filePickBox = this.quickInputService.createQuickPick<FileQuickPickItem>();
this.filePickBox.matchOnLabel = false;
this.filePickBox.autoFocusOnList = false;
this.filePickBox.ok = true;
if (this.options && this.options.availableFileSystems && (this.options.availableFileSystems.length > 1)) {
this.filePickBox.customButton = true;
this.filePickBox.customLabel = nls.localize('remoteFileDialog.local', 'Show Local');
const action = this.allowFileSelection ? (this.allowFolderSelection ? OpenLocalFileFolderAction : OpenLocalFileAction) : OpenLocalFolderAction;
const keybinding = this.keybindingService.lookupKeybinding(action.ID);
if (keybinding) {
const label = keybinding.getLabel();
if (label) {
this.filePickBox.customHover = format('{0} ({1})', action.LABEL, label);
}
}
}
let isResolving = false;
let isAcceptHandled = false;
this.currentFolder = homedir;
this.userEnteredPathSegment = '';
this.autoCompletePathSegment = '';
this.filePickBox.buttons = [this.acceptButton];
this.filePickBox.onDidTriggerButton(_ => {
// accept button
const resolveValue = this.addPostfix(this.remoteUriFrom(this.filePickBox.value));
this.validate(resolveValue).then(validated => {
if (validated) {
isResolving = true;
this.filePickBox.hide();
doResolve(this, resolveValue);
}
});
});
this.filePickBox.title = this.options.title;
this.filePickBox.value = this.pathFromUri(this.currentFolder);
this.filePickBox.value = this.pathFromUri(this.currentFolder, true);
this.filePickBox.valueSelection = [this.filePickBox.value.length, this.filePickBox.value.length];
this.filePickBox.items = [];
function doResolve(dialog: RemoteFileDialog, uri: URI | undefined) {
@@ -217,6 +210,28 @@ export class RemoteFileDialog {
dialog.filePickBox.dispose();
}
this.filePickBox.onDidCustom(() => {
if (isAcceptHandled || this.filePickBox.busy) {
return undefined; // {{SQL CARBON EDIT}} @todo anthonydresser return to return; when we do strict null checks
}
isAcceptHandled = true;
isResolving = true;
if (this.options.availableFileSystems && (this.options.availableFileSystems.length > 1)) {
this.options.availableFileSystems.shift();
}
this.options.defaultUri = undefined;
if (this.requiresTrailing) {
return this.fileDialogService.showSaveDialog(this.options).then(result => {
doResolve(this, result);
});
} else {
return this.fileDialogService.showOpenDialog(this.options).then(result => {
doResolve(this, result ? result[0] : undefined);
});
}
});
this.filePickBox.onDidAccept(_ => {
if (isAcceptHandled || this.filePickBox.busy) {
return;
@@ -247,15 +262,16 @@ export class RemoteFileDialog {
this.filePickBox.onDidChangeValue(async value => {
// onDidChangeValue can also be triggered by the auto complete, so if it looks like the auto complete, don't do anything
if (this.isChangeFromUser()) {
if (value !== this.constructFullUserPath()) {
// If the user has just entered more bad path, don't change anything
if (value !== this.constructFullUserPath() && !this.isBadSubpath(value)) {
this.filePickBox.validationMessage = undefined;
this.shouldOverwriteFile = false;
const valueUri = this.remoteUriFrom(this.trimTrailingSlash(this.filePickBox.value));
let isUpdate = false;
let updated: UpdateResult = UpdateResult.NotUpdated;
if (!resources.isEqual(this.remoteUriFrom(this.trimTrailingSlash(this.pathFromUri(this.currentFolder))), valueUri, true)) {
isUpdate = await this.tryUpdateItems(value, this.remoteUriFrom(this.filePickBox.value));
updated = await this.tryUpdateItems(value, this.remoteUriFrom(this.filePickBox.value));
}
if (!isUpdate) {
if (updated === UpdateResult.NotUpdated) {
this.setActiveItems(value);
}
} else {
@@ -281,6 +297,10 @@ export class RemoteFileDialog {
});
}
private isBadSubpath(value: string) {
return this.badPath && (value.length > this.badPath.length) && equalsIgnoreCase(value.substring(0, this.badPath.length), this.badPath);
}
private isChangeFromUser(): boolean {
if ((this.filePickBox.value === this.pathAppend(this.currentFolder, this.userEnteredPathSegment + this.autoCompletePathSegment))
&& (this.activeItem === (this.filePickBox.activeItems ? this.filePickBox.activeItems[0] : undefined))) {
@@ -294,24 +314,6 @@ export class RemoteFileDialog {
}
private async onDidAccept(): Promise<URI | undefined> {
// Check if Open Local has been selected
const selectedItems: ReadonlyArray<FileQuickPickItem> = this.filePickBox.selectedItems;
if (selectedItems && (selectedItems.length > 0) && (selectedItems[0] === this.fallbackListItem)) {
if (this.options.availableFileSystems && (this.options.availableFileSystems.length > 1)) {
this.options.availableFileSystems.shift();
}
this.options.defaultUri = undefined;
if (this.requiresTrailing) {
return this.fileDialogService.showSaveDialog(this.options).then(result => {
return result;
});
} else {
return this.fileDialogService.showOpenDialog(this.options).then(result => {
return result ? result[0] : undefined;
});
}
}
let resolveValue: URI | undefined;
let navigateValue: URI | undefined;
const trimmedPickBoxValue = ((this.filePickBox.value.length > 1) && this.endsWithSlash(this.filePickBox.value)) ? this.filePickBox.value.substr(0, this.filePickBox.value.length - 1) : this.filePickBox.value;
@@ -360,10 +362,11 @@ export class RemoteFileDialog {
return Promise.resolve(undefined);
}
private async tryUpdateItems(value: string, valueUri: URI): Promise<boolean> {
private async tryUpdateItems(value: string, valueUri: URI): Promise<UpdateResult> {
if (value[value.length - 1] === '~') {
await this.updateItems(this.userHome);
return true;
this.badPath = undefined;
return UpdateResult.Updated;
} else if (this.endsWithSlash(value) || (!resources.isEqual(this.currentFolder, resources.dirname(valueUri), true) && resources.isEqualOrParent(this.currentFolder, resources.dirname(valueUri), true))) {
let stat: IFileStat | undefined;
try {
@@ -373,7 +376,14 @@ export class RemoteFileDialog {
}
if (stat && stat.isDirectory && (resources.basename(valueUri) !== '.') && this.endsWithSlash(value)) {
await this.updateItems(valueUri);
return true;
return UpdateResult.Updated;
} else if (this.endsWithSlash(value)) {
// The input box contains a path that doesn't exist on the system.
this.filePickBox.validationMessage = nls.localize('remoteFileDialog.badPath', 'The path does not exist.');
// Save this bad path. It can take too long to to a stat on every user entered character, but once a user enters a bad path they are likely
// to keep typing more bad path. We can compare against this bad path and see if the user entered path starts with it.
this.badPath = value;
return UpdateResult.InvalidPath;
} else {
const inputUriDirname = resources.dirname(valueUri);
if (!resources.isEqual(this.remoteUriFrom(this.trimTrailingSlash(this.pathFromUri(this.currentFolder))), inputUriDirname, true)) {
@@ -385,12 +395,14 @@ export class RemoteFileDialog {
}
if (statWithoutTrailing && statWithoutTrailing.isDirectory && (resources.basename(valueUri) !== '.')) {
await this.updateItems(inputUriDirname, resources.basename(valueUri));
return true;
this.badPath = undefined;
return UpdateResult.Updated;
}
}
}
}
return false;
this.badPath = undefined;
return UpdateResult.NotUpdated;
}
private setActiveItems(value: string) {
@@ -428,7 +440,7 @@ export class RemoteFileDialog {
this.autoCompletePathSegment = '';
return false;
}
const itemBasename = (quickPickItem.label === '..') ? quickPickItem.label : resources.basename(quickPickItem.uri);
const itemBasename = quickPickItem.label;
// Either force the autocomplete, or the old value should be one smaller than the new value and match the new value.
if (!force && (itemBasename.length >= startingBasename.length) && equalsIgnoreCase(itemBasename.substr(0, startingBasename.length), startingBasename)) {
this.userEnteredPathSegment = startingBasename;
@@ -582,8 +594,11 @@ export class RemoteFileDialog {
if (this.allowFolderSelection) {
this.filePickBox.activeItems = [];
}
this.filePickBox.valueSelection = [0, this.filePickBox.value.length];
this.insertText(newValue, newValue);
if (!equalsIgnoreCase(this.filePickBox.value, newValue)) {
this.filePickBox.valueSelection = [0, this.filePickBox.value.length];
this.insertText(newValue, newValue);
}
this.filePickBox.valueSelection = [this.filePickBox.value.length, this.filePickBox.value.length];
this.filePickBox.busy = false;
});
}
@@ -687,10 +702,6 @@ export class RemoteFileDialog {
if (backDir) {
sorted.unshift(backDir);
}
if (this.fallbackListItem) {
sorted.push(this.fallbackListItem);
}
return sorted;
}
@@ -724,11 +735,4 @@ export class RemoteFileDialog {
return undefined;
}
}
private getDialogIcons(name: string): { light: URI, dark: URI } {
return {
dark: URI.parse(require.toUrl(`vs/workbench/services/dialogs/browser/media/dark/${name}.svg`)),
light: URI.parse(require.toUrl(`vs/workbench/services/dialogs/browser/media/light/${name}.svg`))
};
}
}

View File

@@ -12,8 +12,8 @@ import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/c
import { Registry } from 'vs/platform/registry/common/platform';
import { IMessage } from 'vs/workbench/services/extensions/common/extensions';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { values } from 'vs/base/common/map';
const hasOwnProperty = Object.hasOwnProperty;
const schemaRegistry = Registry.as<IJSONContributionRegistry>(Extensions.JSONContribution);
export type ExtensionKind = 'workspace' | 'ui' | undefined;
@@ -370,18 +370,14 @@ export interface IExtensionPointDescriptor {
export class ExtensionsRegistryImpl {
private _extensionPoints: { [extPoint: string]: ExtensionPoint<any>; };
constructor() {
this._extensionPoints = {};
}
private readonly _extensionPoints = new Map<string, ExtensionPoint<any>>();
public registerExtensionPoint<T>(desc: IExtensionPointDescriptor): IExtensionPoint<T> {
if (hasOwnProperty.call(this._extensionPoints, desc.extensionPoint)) {
if (this._extensionPoints.has(desc.extensionPoint)) {
throw new Error('Duplicate extension point: ' + desc.extensionPoint);
}
let result = new ExtensionPoint<T>(desc.extensionPoint, desc.defaultExtensionKind);
this._extensionPoints[desc.extensionPoint] = result;
const result = new ExtensionPoint<T>(desc.extensionPoint, desc.defaultExtensionKind);
this._extensionPoints.set(desc.extensionPoint, result);
schema.properties['contributes'].properties[desc.extensionPoint] = desc.jsonSchema;
schemaRegistry.registerSchema(schemaId, schema);
@@ -390,11 +386,7 @@ export class ExtensionsRegistryImpl {
}
public getExtensionPoints(): ExtensionPoint<any>[] {
return Object.keys(this._extensionPoints).map(point => this._extensionPoints[point]);
}
public getExtensionPointsMap(): { [extPoint: string]: ExtensionPoint<any>; } {
return this._extensionPoints;
return values(this._extensionPoints);
}
}

View File

@@ -20,6 +20,9 @@ import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { Dialog } from 'vs/base/browser/ui/dialog/dialog';
import { attachDialogStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { EventHelper } from 'vs/base/browser/dom';
export class ProgressService2 implements IProgressService2 {
@@ -34,7 +37,8 @@ export class ProgressService2 implements IProgressService2 {
@INotificationService private readonly _notificationService: INotificationService,
@IStatusbarService private readonly _statusbarService: IStatusbarService,
@ILayoutService private readonly _layoutService: ILayoutService,
@IThemeService private readonly _themeService: IThemeService
@IThemeService private readonly _themeService: IThemeService,
@IKeybindingService private readonly _keybindingService: IKeybindingService
) { }
withProgress<R = unknown>(options: IProgressOptions, task: (progress: IProgress<IProgressStep>) => Promise<R>, onDidCancel?: () => void): Promise<R> {
@@ -276,6 +280,10 @@ export class ProgressService2 implements IProgressService2 {
private _withDialogProgress<P extends Promise<R>, R = unknown>(options: IProgressOptions, task: (progress: IProgress<{ message?: string, increment?: number }>) => P, onDidCancel?: () => void): P {
const disposables: IDisposable[] = [];
const allowableCommands = [
'workbench.action.quit',
'workbench.action.reloadWindow'
];
let dialog: Dialog;
@@ -284,7 +292,17 @@ export class ProgressService2 implements IProgressService2 {
this._layoutService.container,
message,
[options.cancellable ? localize('cancel', "Cancel") : localize('dismiss', "Dismiss")],
{ type: 'pending' }
{
type: 'pending',
keyEventProcessor: (event: StandardKeyboardEvent) => {
const resolved = this._keybindingService.softDispatch(event, this._layoutService.container);
if (resolved && resolved.commandId) {
if (allowableCommands.indexOf(resolved.commandId) === -1) {
EventHelper.stop(event, true);
}
}
}
}
);
disposables.push(dialog);

View File

@@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { IChannel, IServerChannel, getDelayedChannel } from 'vs/base/parts/ipc/common/ipc';
import { Client } from 'vs/base/parts/ipc/common/ipc.net';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { connectRemoteAgentManagement, IConnectionOptions, IWebSocketFactory } from 'vs/platform/remote/common/remoteAgentConnection';
import { connectRemoteAgentManagement, IConnectionOptions, IWebSocketFactory, PersistenConnectionEvent } from 'vs/platform/remote/common/remoteAgentConnection';
import { IRemoteAgentConnection, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
@@ -73,15 +73,18 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon
private readonly _onReconnecting = this._register(new Emitter<void>());
public readonly onReconnecting = this._onReconnecting.event;
private readonly _onDidStateChange = this._register(new Emitter<PersistenConnectionEvent>());
public readonly onDidStateChange = this._onDidStateChange.event;
readonly remoteAuthority: string;
private _connection: Promise<Client<RemoteAgentConnectionContext>> | null;
constructor(
remoteAuthority: string,
private _commit: string | undefined,
private _webSocketFactory: IWebSocketFactory,
private _environmentService: IEnvironmentService,
private _remoteAuthorityResolverService: IRemoteAuthorityResolverService
private readonly _commit: string | undefined,
private readonly _webSocketFactory: IWebSocketFactory,
private readonly _environmentService: IEnvironmentService,
private readonly _remoteAuthorityResolverService: IRemoteAuthorityResolverService
) {
super();
this.remoteAuthority = remoteAuthority;
@@ -121,8 +124,8 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon
}
}
};
const connection = await connectRemoteAgentManagement(options, this.remoteAuthority, `renderer`);
this._register(connection);
const connection = this._register(await connectRemoteAgentManagement(options, this.remoteAuthority, `renderer`));
this._register(connection.onDidStateChange(e => this._onDidStateChange.fire(e)));
return connection.client;
}
}

View File

@@ -8,6 +8,7 @@ import { RemoteAgentConnectionContext, IRemoteAgentEnvironment } from 'vs/platfo
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnosticsService';
import { Event } from 'vs/base/common/event';
import { PersistenConnectionEvent } from 'vs/platform/remote/common/remoteAgentConnection';
export const RemoteExtensionLogFileName = 'remoteagent';
@@ -25,7 +26,9 @@ export interface IRemoteAgentService {
export interface IRemoteAgentConnection {
readonly remoteAuthority: string;
readonly onReconnecting: Event<void>;
readonly onDidStateChange: Event<PersistenConnectionEvent>;
getChannel<T extends IChannel>(channelName: string): T;
registerChannel<T extends IServerChannel<RemoteAgentConnectionContext>>(channelName: string, channel: T): void;
onReconnecting: Event<void>;
}