mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-22 18:47:03 -05:00
Merge from vscode 966b87dd4013be1a9c06e2b8334522ec61905cc2 (#4696)
This commit is contained in:
@@ -90,10 +90,10 @@ export function fillInActionBarActions(menu: IMenu, options: IMenuActionOptions
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}} add export modifier
|
||||
export function fillInActions(groups: [string, Array<MenuItemAction | SubmenuItemAction>][], target: IAction[] | { primary: IAction[]; secondary: IAction[]; }, getAlternativeActions, isPrimaryGroup: (group: string) => boolean = group => group === 'navigation'): void {
|
||||
export function fillInActions(groups: [string, Array<MenuItemAction | SubmenuItemAction>][], target: IAction[] | { primary: IAction[]; secondary: IAction[]; }, useAlternativeActions: boolean, isPrimaryGroup: (group: string) => boolean = group => group === 'navigation'): void {
|
||||
for (let tuple of groups) {
|
||||
let [group, actions] = tuple;
|
||||
if (getAlternativeActions) {
|
||||
if (useAlternativeActions) {
|
||||
actions = actions.map(a => (a instanceof MenuItemAction) && !!a.alt ? a.alt : a);
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ export const enum MenuId {
|
||||
DebugConsoleContext,
|
||||
DebugVariablesContext,
|
||||
DebugWatchContext,
|
||||
DebugToolbar,
|
||||
DebugToolBar,
|
||||
EditorContext,
|
||||
EditorTitle,
|
||||
EditorTitleContext,
|
||||
|
||||
@@ -29,6 +29,8 @@ export interface IConfigurationOverrides {
|
||||
|
||||
export const enum ConfigurationTarget {
|
||||
USER = 1,
|
||||
USER_LOCAL,
|
||||
USER_REMOTE,
|
||||
WORKSPACE,
|
||||
WORKSPACE_FOLDER,
|
||||
DEFAULT,
|
||||
@@ -37,6 +39,8 @@ export const enum ConfigurationTarget {
|
||||
export function ConfigurationTargetToString(configurationTarget: ConfigurationTarget) {
|
||||
switch (configurationTarget) {
|
||||
case ConfigurationTarget.USER: return 'USER';
|
||||
case ConfigurationTarget.USER_LOCAL: return 'USER_LOCAL';
|
||||
case ConfigurationTarget.USER_REMOTE: return 'USER_REMOTE';
|
||||
case ConfigurationTarget.WORKSPACE: return 'WORKSPACE';
|
||||
case ConfigurationTarget.WORKSPACE_FOLDER: return 'WORKSPACE_FOLDER';
|
||||
case ConfigurationTarget.DEFAULT: return 'DEFAULT';
|
||||
@@ -88,6 +92,8 @@ export interface IConfigurationService {
|
||||
inspect<T>(key: string, overrides?: IConfigurationOverrides): {
|
||||
default: T,
|
||||
user: T,
|
||||
userLocal?: T,
|
||||
userRemote?: T,
|
||||
workspace?: T,
|
||||
workspaceFolder?: T,
|
||||
memory?: T,
|
||||
|
||||
@@ -36,6 +36,10 @@ export class ConfigurationModel implements IConfigurationModel {
|
||||
return this.checkAndFreeze(this._keys);
|
||||
}
|
||||
|
||||
isEmpty(): boolean {
|
||||
return this._keys.length === 0 && Object.keys(this._contents).length === 0 && this._overrides.length === 0;
|
||||
}
|
||||
|
||||
getValue<V>(section: string | undefined): V {
|
||||
return section ? getConfigurationValue<any>(this.contents, section) : this.contents;
|
||||
}
|
||||
@@ -284,7 +288,8 @@ export class Configuration {
|
||||
|
||||
constructor(
|
||||
private _defaultConfiguration: ConfigurationModel,
|
||||
private _userConfiguration: ConfigurationModel,
|
||||
private _localUserConfiguration: ConfigurationModel,
|
||||
private _remoteUserConfiguration: ConfigurationModel = new ConfigurationModel(),
|
||||
private _workspaceConfiguration: ConfigurationModel = new ConfigurationModel(),
|
||||
private _folderConfigurations: ResourceMap<ConfigurationModel> = new ResourceMap<ConfigurationModel>(),
|
||||
private _memoryConfiguration: ConfigurationModel = new ConfigurationModel(),
|
||||
@@ -323,6 +328,8 @@ export class Configuration {
|
||||
inspect<C>(key: string, overrides: IConfigurationOverrides, workspace: Workspace | undefined): {
|
||||
default: C,
|
||||
user: C,
|
||||
userLocal?: C,
|
||||
userRemote?: C,
|
||||
workspace?: C,
|
||||
workspaceFolder?: C
|
||||
memory?: C
|
||||
@@ -333,7 +340,9 @@ export class Configuration {
|
||||
const memoryConfigurationModel = overrides.resource ? this._memoryConfigurationByResource.get(overrides.resource) || this._memoryConfiguration : this._memoryConfiguration;
|
||||
return {
|
||||
default: overrides.overrideIdentifier ? this._defaultConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this._defaultConfiguration.freeze().getValue(key),
|
||||
user: overrides.overrideIdentifier ? this._userConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this._userConfiguration.freeze().getValue(key),
|
||||
user: overrides.overrideIdentifier ? this.userConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this.userConfiguration.freeze().getValue(key),
|
||||
userLocal: overrides.overrideIdentifier ? this.localUserConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this.localUserConfiguration.freeze().getValue(key),
|
||||
userRemote: overrides.overrideIdentifier ? this.remoteUserConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this.remoteUserConfiguration.freeze().getValue(key),
|
||||
workspace: workspace ? overrides.overrideIdentifier ? this._workspaceConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this._workspaceConfiguration.freeze().getValue(key) : undefined, //Check on workspace exists or not because _workspaceConfiguration is never null
|
||||
workspaceFolder: folderConfigurationModel ? overrides.overrideIdentifier ? folderConfigurationModel.freeze().override(overrides.overrideIdentifier).getValue(key) : folderConfigurationModel.freeze().getValue(key) : undefined,
|
||||
memory: overrides.overrideIdentifier ? memoryConfigurationModel.override(overrides.overrideIdentifier).getValue(key) : memoryConfigurationModel.getValue(key),
|
||||
@@ -350,7 +359,7 @@ export class Configuration {
|
||||
const folderConfigurationModel = this.getFolderConfigurationModelForResource(undefined, workspace);
|
||||
return {
|
||||
default: this._defaultConfiguration.freeze().keys,
|
||||
user: this._userConfiguration.freeze().keys,
|
||||
user: this.userConfiguration.freeze().keys,
|
||||
workspace: this._workspaceConfiguration.freeze().keys,
|
||||
workspaceFolder: folderConfigurationModel ? folderConfigurationModel.freeze().keys : []
|
||||
};
|
||||
@@ -362,8 +371,16 @@ export class Configuration {
|
||||
this._foldersConsolidatedConfigurations.clear();
|
||||
}
|
||||
|
||||
updateUserConfiguration(userConfiguration: ConfigurationModel): void {
|
||||
this._userConfiguration = userConfiguration;
|
||||
updateLocalUserConfiguration(localUserConfiguration: ConfigurationModel): void {
|
||||
this._localUserConfiguration = localUserConfiguration;
|
||||
this._userConfiguration = null;
|
||||
this._workspaceConsolidatedConfiguration = null;
|
||||
this._foldersConsolidatedConfigurations.clear();
|
||||
}
|
||||
|
||||
updateRemoteUserConfiguration(remoteUserConfiguration: ConfigurationModel): void {
|
||||
this._remoteUserConfiguration = remoteUserConfiguration;
|
||||
this._userConfiguration = null;
|
||||
this._workspaceConsolidatedConfiguration = null;
|
||||
this._foldersConsolidatedConfigurations.clear();
|
||||
}
|
||||
@@ -380,7 +397,7 @@ export class Configuration {
|
||||
}
|
||||
|
||||
deleteFolderConfiguration(resource: URI): void {
|
||||
this.folders.delete(resource);
|
||||
this.folderConfigurations.delete(resource);
|
||||
this._foldersConsolidatedConfigurations.delete(resource);
|
||||
}
|
||||
|
||||
@@ -388,15 +405,30 @@ export class Configuration {
|
||||
return this._defaultConfiguration;
|
||||
}
|
||||
|
||||
get user(): ConfigurationModel {
|
||||
private _userConfiguration: ConfigurationModel | null;
|
||||
get userConfiguration(): ConfigurationModel {
|
||||
if (!this._userConfiguration) {
|
||||
this._userConfiguration = this._remoteUserConfiguration.isEmpty() ? this._localUserConfiguration : this._localUserConfiguration.merge(this._remoteUserConfiguration);
|
||||
if (this._freeze) {
|
||||
this._userConfiguration.freeze();
|
||||
}
|
||||
}
|
||||
return this._userConfiguration;
|
||||
}
|
||||
|
||||
get workspace(): ConfigurationModel {
|
||||
get localUserConfiguration(): ConfigurationModel {
|
||||
return this._localUserConfiguration;
|
||||
}
|
||||
|
||||
get remoteUserConfiguration(): ConfigurationModel {
|
||||
return this._remoteUserConfiguration;
|
||||
}
|
||||
|
||||
get workspaceConfiguration(): ConfigurationModel {
|
||||
return this._workspaceConfiguration;
|
||||
}
|
||||
|
||||
protected get folders(): ResourceMap<ConfigurationModel> {
|
||||
protected get folderConfigurations(): ResourceMap<ConfigurationModel> {
|
||||
return this._folderConfigurations;
|
||||
}
|
||||
|
||||
@@ -424,7 +456,7 @@ export class Configuration {
|
||||
|
||||
private getWorkspaceConsolidatedConfiguration(): ConfigurationModel {
|
||||
if (!this._workspaceConsolidatedConfiguration) {
|
||||
this._workspaceConsolidatedConfiguration = this._defaultConfiguration.merge(this._userConfiguration, this._workspaceConfiguration, this._memoryConfiguration);
|
||||
this._workspaceConsolidatedConfiguration = this._defaultConfiguration.merge(this.userConfiguration, this._workspaceConfiguration, this._memoryConfiguration);
|
||||
if (this._freeze) {
|
||||
this._workspaceConfiguration = this._workspaceConfiguration.freeze();
|
||||
}
|
||||
@@ -468,9 +500,9 @@ export class Configuration {
|
||||
keys: this._defaultConfiguration.keys
|
||||
},
|
||||
user: {
|
||||
contents: this._userConfiguration.contents,
|
||||
overrides: this._userConfiguration.overrides,
|
||||
keys: this._userConfiguration.keys
|
||||
contents: this.userConfiguration.contents,
|
||||
overrides: this.userConfiguration.overrides,
|
||||
keys: this.userConfiguration.keys
|
||||
},
|
||||
workspace: {
|
||||
contents: this._workspaceConfiguration.contents,
|
||||
@@ -489,7 +521,7 @@ export class Configuration {
|
||||
allKeys(workspace: Workspace | undefined): string[] {
|
||||
let keys = this.keys(workspace);
|
||||
let all = [...keys.default];
|
||||
const addKeys = (keys) => {
|
||||
const addKeys = (keys: string[]) => {
|
||||
for (const key of keys) {
|
||||
if (all.indexOf(key) === -1) {
|
||||
all.push(key);
|
||||
@@ -498,8 +530,8 @@ export class Configuration {
|
||||
};
|
||||
addKeys(keys.user);
|
||||
addKeys(keys.workspace);
|
||||
for (const resource of this.folders.keys()) {
|
||||
addKeys(this.folders.get(resource)!.keys);
|
||||
for (const resource of this.folderConfigurations.keys()) {
|
||||
addKeys(this.folderConfigurations.get(resource)!.keys);
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
@@ -3,13 +3,17 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { ConfigurationModelParser, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { ConfigWatcher } from 'vs/base/node/config';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IFileService, FileChangesEvent } from 'vs/platform/files/common/files';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
|
||||
export class UserConfiguration extends Disposable {
|
||||
export class NodeBasedUserConfiguration extends Disposable {
|
||||
|
||||
private userConfigModelWatcher: ConfigWatcher<ConfigurationModelParser>;
|
||||
private initializePromise: Promise<void>;
|
||||
@@ -50,4 +54,53 @@ export class UserConfiguration extends Disposable {
|
||||
return this.initialize().then(() => new Promise<ConfigurationModel>(c => this.userConfigModelWatcher.reload(userConfigModelParser => c(userConfigModelParser.configurationModel))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class FileServiceBasedUserConfiguration extends Disposable {
|
||||
|
||||
private readonly reloadConfigurationScheduler: RunOnceScheduler;
|
||||
protected readonly _onDidChangeConfiguration: Emitter<ConfigurationModel> = this._register(new Emitter<ConfigurationModel>());
|
||||
readonly onDidChangeConfiguration: Event<ConfigurationModel> = this._onDidChangeConfiguration.event;
|
||||
|
||||
constructor(
|
||||
private readonly configurationResource: URI,
|
||||
private readonly fileService: IFileService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._register(fileService.onFileChanges(e => this.handleFileEvents(e)));
|
||||
this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50));
|
||||
this.fileService.watchFileChanges(this.configurationResource);
|
||||
this._register(toDisposable(() => this.fileService.unwatchFileChanges(this.configurationResource)));
|
||||
}
|
||||
|
||||
initialize(): Promise<ConfigurationModel> {
|
||||
return this.reload();
|
||||
}
|
||||
|
||||
reload(): Promise<ConfigurationModel> {
|
||||
return this.fileService.resolveContent(this.configurationResource)
|
||||
.then(content => content.value, () => {
|
||||
// File not found
|
||||
return '';
|
||||
}).then(content => {
|
||||
const parser = new ConfigurationModelParser(this.configurationResource.toString());
|
||||
parser.parse(content);
|
||||
return parser.configurationModel;
|
||||
});
|
||||
}
|
||||
|
||||
private handleFileEvents(event: FileChangesEvent): void {
|
||||
const events = event.changes;
|
||||
|
||||
let affectedByChanges = false;
|
||||
// Find changes that affect workspace file
|
||||
for (let i = 0, len = events.length; i < len && !affectedByChanges; i++) {
|
||||
affectedByChanges = resources.isEqual(this.configurationResource, events[i].resource);
|
||||
}
|
||||
|
||||
if (affectedByChanges) {
|
||||
this.reloadConfigurationScheduler.schedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,14 +11,14 @@ import { DefaultConfigurationModel, Configuration, ConfigurationChangeEvent, Con
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { UserConfiguration } from 'vs/platform/configuration/node/configuration';
|
||||
import { NodeBasedUserConfiguration } from 'vs/platform/configuration/node/configuration';
|
||||
|
||||
export class ConfigurationService extends Disposable implements IConfigurationService, IDisposable {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private _configuration: Configuration;
|
||||
private userConfiguration: UserConfiguration;
|
||||
private userConfiguration: NodeBasedUserConfiguration;
|
||||
|
||||
private readonly _onDidChangeConfiguration: Emitter<IConfigurationChangeEvent> = this._register(new Emitter<IConfigurationChangeEvent>());
|
||||
readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
|
||||
@@ -28,7 +28,7 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
|
||||
) {
|
||||
super();
|
||||
|
||||
this.userConfiguration = this._register(new UserConfiguration(environmentService.appSettingsPath));
|
||||
this.userConfiguration = this._register(new NodeBasedUserConfiguration(environmentService.appSettingsPath));
|
||||
|
||||
// Initialize
|
||||
const defaults = new DefaultConfigurationModel();
|
||||
@@ -91,10 +91,10 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
|
||||
}
|
||||
|
||||
private onDidChangeUserConfiguration(userConfigurationModel: ConfigurationModel): void {
|
||||
const { added, updated, removed } = compare(this._configuration.user, userConfigurationModel);
|
||||
const { added, updated, removed } = compare(this._configuration.localUserConfiguration, userConfigurationModel);
|
||||
const changedKeys = [...added, ...updated, ...removed];
|
||||
if (changedKeys.length) {
|
||||
this._configuration.updateUserConfiguration(userConfigurationModel);
|
||||
this._configuration.updateLocalUserConfiguration(userConfigurationModel);
|
||||
this.trigger(changedKeys, ConfigurationTarget.USER);
|
||||
}
|
||||
}
|
||||
@@ -113,7 +113,7 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
|
||||
case ConfigurationTarget.DEFAULT:
|
||||
return this._configuration.defaults.contents;
|
||||
case ConfigurationTarget.USER:
|
||||
return this._configuration.user.contents;
|
||||
return this._configuration.localUserConfiguration.contents;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@ export class TestConfigurationService implements IConfigurationService {
|
||||
public inspect<T>(key: string, overrides?: IConfigurationOverrides): {
|
||||
default: T,
|
||||
user: T,
|
||||
userLocal?: T,
|
||||
userRemote?: T,
|
||||
workspace?: T,
|
||||
workspaceFolder?: T
|
||||
value: T,
|
||||
|
||||
@@ -26,7 +26,7 @@ export interface IDiagnosticsService {
|
||||
formatEnvironment(info: IMainProcessInfo): string;
|
||||
getPerformanceInfo(info: IMainProcessInfo): Promise<PerformanceInfo>;
|
||||
getSystemInfo(info: IMainProcessInfo): SystemInfo;
|
||||
printDiagnostics(info: IMainProcessInfo): Promise<any>;
|
||||
getDiagnostics(info: IMainProcessInfo): Promise<string>;
|
||||
}
|
||||
|
||||
export interface VersionInfo {
|
||||
@@ -156,28 +156,29 @@ export class DiagnosticsService implements IDiagnosticsService {
|
||||
return systemInfo;
|
||||
}
|
||||
|
||||
printDiagnostics(info: IMainProcessInfo): Promise<any> {
|
||||
getDiagnostics(info: IMainProcessInfo): Promise<string> {
|
||||
const output: string[] = [];
|
||||
return listProcesses(info.mainPID).then(rootProcess => {
|
||||
|
||||
// Environment Info
|
||||
console.log('');
|
||||
console.log(this.formatEnvironment(info));
|
||||
output.push('');
|
||||
output.push(this.formatEnvironment(info));
|
||||
|
||||
// Process List
|
||||
console.log('');
|
||||
console.log(this.formatProcessList(info, rootProcess));
|
||||
output.push('');
|
||||
output.push(this.formatProcessList(info, rootProcess));
|
||||
|
||||
// Workspace Stats
|
||||
const workspaceStatPromises: Promise<void>[] = [];
|
||||
if (info.windows.some(window => window.folderURIs && window.folderURIs.length > 0)) {
|
||||
console.log('');
|
||||
console.log('Workspace Stats: ');
|
||||
output.push('');
|
||||
output.push('Workspace Stats: ');
|
||||
info.windows.forEach(window => {
|
||||
if (window.folderURIs.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`| Window (${window.title})`);
|
||||
output.push(`| Window (${window.title})`);
|
||||
|
||||
window.folderURIs.forEach(uriComponents => {
|
||||
const folderUri = URI.revive(uriComponents);
|
||||
@@ -188,22 +189,24 @@ export class DiagnosticsService implements IDiagnosticsService {
|
||||
if (stats.maxFilesReached) {
|
||||
countMessage = `more than ${countMessage}`;
|
||||
}
|
||||
console.log(`| Folder (${basename(folder)}): ${countMessage}`);
|
||||
console.log(this.formatWorkspaceStats(stats));
|
||||
output.push(`| Folder (${basename(folder)}): ${countMessage}`);
|
||||
output.push(this.formatWorkspaceStats(stats));
|
||||
|
||||
}).catch(error => {
|
||||
console.log(`| Error: Unable to collect workspace stats for folder ${folder} (${error.toString()})`);
|
||||
output.push(`| Error: Unable to collect workspace stats for folder ${folder} (${error.toString()})`);
|
||||
}));
|
||||
} else {
|
||||
console.log(`| Folder (${folderUri.toString()}): Workspace stats not available.`);
|
||||
output.push(`| Folder (${folderUri.toString()}): Workspace stats not available.`);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.all(workspaceStatPromises).then(() => {
|
||||
console.log('');
|
||||
console.log('');
|
||||
output.push('');
|
||||
output.push('');
|
||||
|
||||
return output.join('\n');
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -340,7 +343,7 @@ function asSortedItems(map: Map<string, number>): WorkspaceStatItem[] {
|
||||
// const errors: ParseError[] = [];
|
||||
// const json = parse(contents.toString(), errors);
|
||||
// if (errors.length) {
|
||||
// console.log(`Unable to parse ${launchConfig}`);
|
||||
// output.push(`Unable to parse ${launchConfig}`);
|
||||
// return resolve([]);
|
||||
// }
|
||||
|
||||
|
||||
92
src/vs/platform/dialogs/browser/dialogService.ts
Normal file
92
src/vs/platform/dialogs/browser/dialogService.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { IDialogService, IDialogOptions, IConfirmation, IConfirmationResult, DialogType } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { Dialog } from 'vs/base/browser/ui/dialog/dialog';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { attachDialogStyler } from 'vs/platform/theme/common/styler';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export class DialogService implements IDialogService {
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor(
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@ILayoutService private readonly layoutService: ILayoutService,
|
||||
@IThemeService private readonly themeService: IThemeService
|
||||
) { }
|
||||
|
||||
async confirm(confirmation: IConfirmation): Promise<IConfirmationResult> {
|
||||
this.logService.trace('DialogService#confirm', confirmation.message);
|
||||
|
||||
const buttons: string[] = [];
|
||||
if (confirmation.primaryButton) {
|
||||
buttons.push(confirmation.primaryButton);
|
||||
} else {
|
||||
buttons.push(nls.localize({ key: 'yesButton', comment: ['&& denotes a mnemonic'] }, "&&Yes"));
|
||||
}
|
||||
|
||||
if (confirmation.secondaryButton) {
|
||||
buttons.push(confirmation.secondaryButton);
|
||||
} else if (typeof confirmation.secondaryButton === 'undefined') {
|
||||
buttons.push(nls.localize('cancelButton', "Cancel"));
|
||||
}
|
||||
|
||||
const severity = this.getSeverity(confirmation.type || 'none');
|
||||
const result = await this.show(severity, confirmation.message, buttons, { cancelId: 1, detail: confirmation.detail });
|
||||
|
||||
return { confirmed: result === 0 };
|
||||
}
|
||||
|
||||
private getSeverity(type: DialogType): Severity {
|
||||
switch (type) {
|
||||
case 'error':
|
||||
return Severity.Error;
|
||||
case 'warning':
|
||||
return Severity.Warning;
|
||||
case 'question':
|
||||
case 'info':
|
||||
return Severity.Info;
|
||||
case 'none':
|
||||
default:
|
||||
return Severity.Ignore;
|
||||
}
|
||||
}
|
||||
|
||||
private getDialogType(severity: Severity): DialogType {
|
||||
return (severity === Severity.Info) ? 'question' : (severity === Severity.Error) ? 'error' : (severity === Severity.Warning) ? 'warning' : 'none';
|
||||
}
|
||||
|
||||
|
||||
async show(severity: Severity, message: string, buttons: string[], options?: IDialogOptions): Promise<number> {
|
||||
this.logService.trace('DialogService#show', message);
|
||||
|
||||
const dialogDisposables: IDisposable[] = [];
|
||||
const dialog = new Dialog(
|
||||
this.layoutService.container,
|
||||
message,
|
||||
buttons,
|
||||
{
|
||||
detail: options ? options.detail : undefined,
|
||||
cancelId: options ? options.cancelId : undefined,
|
||||
type: this.getDialogType(severity)
|
||||
});
|
||||
|
||||
dialogDisposables.push(dialog);
|
||||
dialogDisposables.push(attachDialogStyler(dialog, this.themeService));
|
||||
|
||||
const choice = await dialog.show();
|
||||
dispose(dialogDisposables);
|
||||
|
||||
return choice;
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(IDialogService, DialogService, true);
|
||||
@@ -11,9 +11,11 @@ import { localize } from 'vs/nls';
|
||||
import { FileFilter } from 'vs/platform/windows/common/windows';
|
||||
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
export type DialogType = 'none' | 'info' | 'error' | 'question' | 'warning';
|
||||
|
||||
export interface IConfirmation {
|
||||
title?: string;
|
||||
type?: 'none' | 'info' | 'error' | 'question' | 'warning';
|
||||
type?: DialogType;
|
||||
message: string;
|
||||
detail?: string;
|
||||
primaryButton?: string;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
|
||||
import { serve as serveNet } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { combinedDisposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IPCServer, StaticRouter } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { IPCServer, StaticRouter } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { SimpleKeybinding, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
|
||||
import { OS } from 'vs/base/common/platform';
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { connect as connectNet, Client } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { Client } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
@@ -7,6 +7,8 @@ import * as minimist from 'minimist';
|
||||
import * as os from 'os';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { join } from 'path';
|
||||
import { writeFileSync } from 'fs';
|
||||
|
||||
/**
|
||||
* This code is also used by standalone cli's. Avoid adding any other dependencies.
|
||||
@@ -263,3 +265,20 @@ export function addArg(argv: string[], ...args: string[]): string[] {
|
||||
|
||||
return argv;
|
||||
}
|
||||
|
||||
export function createWaitMarkerFile(verbose?: boolean): string | undefined {
|
||||
const randomWaitMarkerPath = join(os.tmpdir(), Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 10));
|
||||
|
||||
try {
|
||||
writeFileSync(randomWaitMarkerPath, '');
|
||||
if (verbose) {
|
||||
console.log(`Marker file for --wait created: ${randomWaitMarkerPath}`);
|
||||
}
|
||||
return randomWaitMarkerPath;
|
||||
} catch (err) {
|
||||
if (verbose) {
|
||||
console.error(`Failed to create marker file for --wait: ${err}`);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { tmpdir } from 'os';
|
||||
import { firstIndex } from 'vs/base/common/arrays';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ParsedArgs } from '../common/environment';
|
||||
import { MIN_MAX_MEMORY_SIZE_MB } from 'vs/platform/files/common/files';
|
||||
import { parseArgs } from 'vs/platform/environment/node/argv';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { writeFile } from 'vs/base/node/pfs';
|
||||
|
||||
function validate(args: ParsedArgs): ParsedArgs {
|
||||
if (args.goto) {
|
||||
@@ -60,21 +57,3 @@ export function parseCLIProcessArgv(processArgv: string[]): ParsedArgs {
|
||||
|
||||
return validate(parseArgs(args));
|
||||
}
|
||||
|
||||
export function createWaitMarkerFile(verbose?: boolean): Promise<string> {
|
||||
const randomWaitMarkerPath = join(tmpdir(), Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 10));
|
||||
|
||||
return writeFile(randomWaitMarkerPath, '').then(() => {
|
||||
if (verbose) {
|
||||
console.log(`Marker file for --wait created: ${randomWaitMarkerPath}`);
|
||||
}
|
||||
|
||||
return randomWaitMarkerPath;
|
||||
}, error => {
|
||||
if (verbose) {
|
||||
console.error(`Failed to create marker file for --wait: ${error}`);
|
||||
}
|
||||
|
||||
return Promise.resolve(undefined);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -56,6 +56,11 @@ export interface IFileService {
|
||||
*/
|
||||
canHandleResource(resource: URI): boolean;
|
||||
|
||||
/**
|
||||
* Checks if the provider for the provided resource has the provided file system capability.
|
||||
*/
|
||||
hasCapability(resource: URI, capability: FileSystemProviderCapabilities): Promise<boolean>;
|
||||
|
||||
//#endregion
|
||||
|
||||
/**
|
||||
@@ -188,6 +193,7 @@ export interface FileOpenOptions {
|
||||
|
||||
export interface FileDeleteOptions {
|
||||
recursive: boolean;
|
||||
useTrash: boolean;
|
||||
}
|
||||
|
||||
export enum FileType {
|
||||
@@ -215,7 +221,9 @@ export const enum FileSystemProviderCapabilities {
|
||||
FileFolderCopy = 1 << 3,
|
||||
|
||||
PathCaseSensitive = 1 << 10,
|
||||
Readonly = 1 << 11
|
||||
Readonly = 1 << 11,
|
||||
|
||||
Trash = 1 << 12
|
||||
}
|
||||
|
||||
export interface IFileSystemProvider {
|
||||
@@ -243,6 +251,34 @@ export interface IFileSystemProvider {
|
||||
write?(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number>;
|
||||
}
|
||||
|
||||
export interface IFileSystemProviderWithFileReadWriteCapability extends IFileSystemProvider {
|
||||
readFile(resource: URI): Promise<Uint8Array>;
|
||||
writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): Promise<void>;
|
||||
}
|
||||
|
||||
export function hasReadWriteCapability(provider: IFileSystemProvider): provider is IFileSystemProviderWithFileReadWriteCapability {
|
||||
return !!(provider.capabilities & FileSystemProviderCapabilities.FileReadWrite);
|
||||
}
|
||||
|
||||
export interface IFileSystemProviderWithFileFolderCopyCapability extends IFileSystemProvider {
|
||||
copy(from: URI, to: URI, opts: FileOverwriteOptions): Promise<void>;
|
||||
}
|
||||
|
||||
export function hasFileFolderCopyCapability(provider: IFileSystemProvider): provider is IFileSystemProviderWithFileFolderCopyCapability {
|
||||
return !!(provider.capabilities & FileSystemProviderCapabilities.FileFolderCopy);
|
||||
}
|
||||
|
||||
export interface IFileSystemProviderWithOpenReadWriteCloseCapability extends IFileSystemProvider {
|
||||
open(resource: URI, opts: FileOpenOptions): Promise<number>;
|
||||
close(fd: number): Promise<void>;
|
||||
read(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number>;
|
||||
write(fd: number, pos: number, data: Uint8Array, offset: number, length: number): Promise<number>;
|
||||
}
|
||||
|
||||
export function hasOpenReadWriteCloseCapability(provider: IFileSystemProvider): provider is IFileSystemProviderWithOpenReadWriteCloseCapability {
|
||||
return !!(provider.capabilities & FileSystemProviderCapabilities.FileOpenReadWriteClose);
|
||||
}
|
||||
|
||||
export enum FileSystemProviderErrorCode {
|
||||
FileExists = 'EntryExists',
|
||||
FileNotFound = 'EntryNotFound',
|
||||
@@ -1103,8 +1139,6 @@ export interface ILegacyFileService {
|
||||
|
||||
createFile(resource: URI, content?: string, options?: ICreateFileOptions): Promise<IFileStat>;
|
||||
|
||||
del(resource: URI, options?: { useTrash?: boolean, recursive?: boolean }): Promise<void>;
|
||||
|
||||
watchFileChanges(resource: URI): void;
|
||||
|
||||
unwatchFileChanges(resource: URI): void;
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Client, connect } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { Client } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { connect } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { IWindowsService, IWindowService } from 'vs/platform/windows/common/windows';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { getDelayedChannel } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IChannel, IServerChannel, getDelayedChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
|
||||
export const ISharedProcessService = createDecorator<ISharedProcessService>('sharedProcessService');
|
||||
|
||||
|
||||
@@ -89,4 +89,5 @@ export interface IIssueService {
|
||||
_serviceBrand: any;
|
||||
openReporter(data: IssueReporterData): Promise<void>;
|
||||
openProcessExplorer(data: ProcessExplorerData): Promise<void>;
|
||||
getSystemStatus(): Promise<string>;
|
||||
}
|
||||
|
||||
@@ -25,4 +25,8 @@ export class IssueService implements IIssueService {
|
||||
openProcessExplorer(data: ProcessExplorerData): Promise<void> {
|
||||
return this.channel.call('openProcessExplorer', data);
|
||||
}
|
||||
|
||||
getSystemStatus(): Promise<string> {
|
||||
return this.channel.call('getSystemStatus');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,6 +214,12 @@ export class IssueService implements IIssueService {
|
||||
});
|
||||
}
|
||||
|
||||
public getSystemStatus(): Promise<string> {
|
||||
return this.launchService.getMainProcessInfo().then(info => {
|
||||
return this.diagnosticsService.getDiagnostics(info);
|
||||
});
|
||||
}
|
||||
|
||||
private getWindowPosition(parentWindow: BrowserWindow, defaultWidth: number, defaultHeight: number): IWindowState {
|
||||
// We want the new window to open on the same display that the parent is in
|
||||
let displayToUse: Electron.Display | undefined;
|
||||
|
||||
@@ -21,6 +21,8 @@ export class IssueChannel implements IServerChannel {
|
||||
return this.service.openReporter(arg);
|
||||
case 'openProcessExplorer':
|
||||
return this.service.openProcessExplorer(arg);
|
||||
case 'getSystemStatus':
|
||||
return this.service.getSystemStatus();
|
||||
}
|
||||
|
||||
throw new Error(`Call not found: ${command}`);
|
||||
|
||||
@@ -163,9 +163,11 @@ export class LaunchService implements ILaunchService {
|
||||
const context = !!userEnv['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP;
|
||||
let usedWindows: ICodeWindow[] = [];
|
||||
|
||||
const waitMarkerFileURI = args.wait && args.waitMarkerFilePath ? URI.file(args.waitMarkerFilePath) : undefined;
|
||||
|
||||
// Special case extension development
|
||||
if (!!args.extensionDevelopmentPath) {
|
||||
this.windowsMainService.openExtensionDevelopmentHostWindow(args.extensionDevelopmentPath, { context, cli: args, userEnv });
|
||||
this.windowsMainService.openExtensionDevelopmentHostWindow(args.extensionDevelopmentPath, { context, cli: args, userEnv, waitMarkerFileURI });
|
||||
}
|
||||
|
||||
// Start without file/folder arguments
|
||||
@@ -199,7 +201,14 @@ export class LaunchService implements ILaunchService {
|
||||
}
|
||||
|
||||
if (openNewWindow) {
|
||||
usedWindows = this.windowsMainService.open({ context, cli: args, userEnv, forceNewWindow: true, forceEmpty: true });
|
||||
usedWindows = this.windowsMainService.open({
|
||||
context,
|
||||
cli: args,
|
||||
userEnv,
|
||||
forceNewWindow: true,
|
||||
forceEmpty: true,
|
||||
waitMarkerFileURI
|
||||
});
|
||||
} else {
|
||||
usedWindows = [this.windowsMainService.focusLastActive(args, context)];
|
||||
}
|
||||
@@ -216,7 +225,8 @@ export class LaunchService implements ILaunchService {
|
||||
forceReuseWindow: args['reuse-window'],
|
||||
diffMode: args.diff,
|
||||
addMode: args.add,
|
||||
noRecentEntry: !!args['skip-add-to-recently-opened']
|
||||
noRecentEntry: !!args['skip-add-to-recently-opened'],
|
||||
waitMarkerFileURI
|
||||
});
|
||||
}
|
||||
|
||||
@@ -232,10 +242,10 @@ export class LaunchService implements ILaunchService {
|
||||
// If the other instance is waiting to be killed, we hook up a window listener if one window
|
||||
// is being used and only then resolve the startup promise which will kill this second instance.
|
||||
// In addition, we poll for the wait marker file to be deleted to return.
|
||||
if (args.wait && args.waitMarkerFilePath && usedWindows.length === 1 && usedWindows[0]) {
|
||||
if (waitMarkerFileURI && usedWindows.length === 1 && usedWindows[0]) {
|
||||
return Promise.race([
|
||||
this.windowsMainService.waitForWindowCloseOrLoad(usedWindows[0].id),
|
||||
whenDeleted(args.waitMarkerFilePath)
|
||||
whenDeleted(waitMarkerFileURI.fsPath)
|
||||
]).then(() => undefined, () => undefined);
|
||||
}
|
||||
|
||||
|
||||
@@ -195,6 +195,8 @@ export interface IQuickPick<T extends IQuickPickItem> extends IQuickInput {
|
||||
valueSelection: Readonly<[number, number]> | undefined;
|
||||
|
||||
validationMessage: string | undefined;
|
||||
|
||||
inputHasFocus(): boolean;
|
||||
}
|
||||
|
||||
export interface IInputBox extends IQuickInput {
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ResolvedAuthority, IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
|
||||
export class RemoteAuthorityResolverService implements IRemoteAuthorityResolverService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
resolveAuthority(authority: string): Promise<ResolvedAuthority> {
|
||||
if (authority.indexOf(':') >= 0) {
|
||||
const pieces = authority.split(':');
|
||||
return Promise.resolve({ authority, host: pieces[0], port: parseInt(pieces[1], 10) });
|
||||
}
|
||||
return Promise.resolve({ authority, host: authority, port: 80 });
|
||||
}
|
||||
|
||||
setResolvedAuthority(resolvedAuthority: ResolvedAuthority) {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
|
||||
setResolvedAuthorityError(authority: string, err: any): void {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
}
|
||||
207
src/vs/platform/remote/common/remoteAgentConnection.ts
Normal file
207
src/vs/platform/remote/common/remoteAgentConnection.ts
Normal file
@@ -0,0 +1,207 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Client, PersistentProtocol, ISocket } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { RemoteAgentConnectionContext } from 'vs/platform/remote/common/remoteAgentEnvironment';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export const enum ConnectionType {
|
||||
Management = 1,
|
||||
ExtensionHost = 2,
|
||||
Tunnel = 3,
|
||||
}
|
||||
|
||||
interface ISimpleConnectionOptions {
|
||||
isBuilt: boolean;
|
||||
commit: string | undefined;
|
||||
host: string;
|
||||
port: number;
|
||||
reconnectionToken: string;
|
||||
reconnectionProtocol: PersistentProtocol | null;
|
||||
webSocketFactory: IWebSocketFactory;
|
||||
}
|
||||
|
||||
export interface IConnectCallback {
|
||||
(err: any | undefined, socket: ISocket | undefined): void;
|
||||
}
|
||||
|
||||
export interface IWebSocketFactory {
|
||||
connect(host: string, port: number, query: string, callback: IConnectCallback): void;
|
||||
}
|
||||
|
||||
async function connectToRemoteExtensionHostAgent(options: ISimpleConnectionOptions, connectionType: ConnectionType, args: any | undefined): Promise<PersistentProtocol> {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
|
||||
interface IManagementConnectionResult {
|
||||
protocol: PersistentProtocol;
|
||||
}
|
||||
|
||||
async function doConnectRemoteAgentManagement(options: ISimpleConnectionOptions): Promise<IManagementConnectionResult> {
|
||||
const protocol = await connectToRemoteExtensionHostAgent(options, ConnectionType.Management, undefined);
|
||||
return new Promise<IManagementConnectionResult>((c, e) => {
|
||||
const registration = protocol.onControlMessage(raw => {
|
||||
registration.dispose();
|
||||
const msg = JSON.parse(raw.toString());
|
||||
const error = getErrorFromMessage(msg);
|
||||
if (error) {
|
||||
return e(error);
|
||||
}
|
||||
if (options.reconnectionProtocol) {
|
||||
options.reconnectionProtocol.endAcceptReconnection();
|
||||
}
|
||||
c({ protocol });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export interface IRemoteExtensionHostStartParams {
|
||||
language: string;
|
||||
debugId?: string;
|
||||
break?: boolean;
|
||||
port?: number | null;
|
||||
updatePort?: boolean;
|
||||
}
|
||||
|
||||
interface IExtensionHostConnectionResult {
|
||||
protocol: PersistentProtocol;
|
||||
debugPort?: number;
|
||||
}
|
||||
|
||||
async function doConnectRemoteAgentExtensionHost(options: ISimpleConnectionOptions, startArguments: IRemoteExtensionHostStartParams): Promise<IExtensionHostConnectionResult> {
|
||||
const protocol = await connectToRemoteExtensionHostAgent(options, ConnectionType.ExtensionHost, startArguments);
|
||||
return new Promise<IExtensionHostConnectionResult>((c, e) => {
|
||||
const registration = protocol.onControlMessage(raw => {
|
||||
registration.dispose();
|
||||
const msg = JSON.parse(raw.toString());
|
||||
const error = getErrorFromMessage(msg);
|
||||
if (error) {
|
||||
return e(error);
|
||||
}
|
||||
const debugPort = msg && msg.debugPort;
|
||||
if (options.reconnectionProtocol) {
|
||||
options.reconnectionProtocol.endAcceptReconnection();
|
||||
}
|
||||
c({ protocol, debugPort });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export interface ITunnelConnectionStartParams {
|
||||
port: number;
|
||||
}
|
||||
|
||||
async function doConnectRemoteAgentTunnel(options: ISimpleConnectionOptions, startParams: ITunnelConnectionStartParams): Promise<PersistentProtocol> {
|
||||
const protocol = await connectToRemoteExtensionHostAgent(options, ConnectionType.Tunnel, startParams);
|
||||
return protocol;
|
||||
}
|
||||
|
||||
export interface IConnectionOptions {
|
||||
isBuilt: boolean;
|
||||
commit: string | undefined;
|
||||
webSocketFactory: IWebSocketFactory;
|
||||
addressProvider: IAddressProvider;
|
||||
}
|
||||
|
||||
async function resolveConnectionOptions(options: IConnectionOptions, reconnectionToken: string, reconnectionProtocol: PersistentProtocol | null): Promise<ISimpleConnectionOptions> {
|
||||
const { host, port } = await options.addressProvider.getAddress();
|
||||
return {
|
||||
isBuilt: options.isBuilt,
|
||||
commit: options.commit,
|
||||
host: host,
|
||||
port: port,
|
||||
reconnectionToken: reconnectionToken,
|
||||
reconnectionProtocol: reconnectionProtocol,
|
||||
webSocketFactory: options.webSocketFactory,
|
||||
};
|
||||
}
|
||||
|
||||
export interface IAddress {
|
||||
host: string;
|
||||
port: number;
|
||||
}
|
||||
|
||||
export interface IAddressProvider {
|
||||
getAddress(): Promise<IAddress>;
|
||||
}
|
||||
|
||||
export async function connectRemoteAgentManagement(options: IConnectionOptions, remoteAuthority: string, clientId: string): Promise<ManagementPersistentConnection> {
|
||||
const reconnectionToken = generateUuid();
|
||||
const simpleOptions = await resolveConnectionOptions(options, reconnectionToken, null);
|
||||
const { protocol } = await doConnectRemoteAgentManagement(simpleOptions);
|
||||
return new ManagementPersistentConnection(options, remoteAuthority, clientId, reconnectionToken, protocol);
|
||||
}
|
||||
|
||||
export async function connectRemoteAgentExtensionHost(options: IConnectionOptions, startArguments: IRemoteExtensionHostStartParams): Promise<ExtensionHostPersistentConnection> {
|
||||
const reconnectionToken = generateUuid();
|
||||
const simpleOptions = await resolveConnectionOptions(options, reconnectionToken, null);
|
||||
const { protocol, debugPort } = await doConnectRemoteAgentExtensionHost(simpleOptions, startArguments);
|
||||
return new ExtensionHostPersistentConnection(options, startArguments, reconnectionToken, protocol, debugPort);
|
||||
}
|
||||
|
||||
export async function connectRemoteAgentTunnel(options: IConnectionOptions, tunnelRemotePort: number): Promise<PersistentProtocol> {
|
||||
const simpleOptions = await resolveConnectionOptions(options, generateUuid(), null);
|
||||
const protocol = await doConnectRemoteAgentTunnel(simpleOptions, { port: tunnelRemotePort });
|
||||
return protocol;
|
||||
}
|
||||
|
||||
abstract class PersistentConnection extends Disposable {
|
||||
|
||||
protected readonly _options: IConnectionOptions;
|
||||
public readonly reconnectionToken: string;
|
||||
public readonly protocol: PersistentProtocol;
|
||||
|
||||
constructor(options: IConnectionOptions, reconnectionToken: string, protocol: PersistentProtocol) {
|
||||
super();
|
||||
this._options = options;
|
||||
this.reconnectionToken = reconnectionToken;
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
protected abstract _reconnect(options: ISimpleConnectionOptions): Promise<void>;
|
||||
}
|
||||
|
||||
export class ManagementPersistentConnection extends PersistentConnection {
|
||||
|
||||
public readonly client: Client<RemoteAgentConnectionContext>;
|
||||
|
||||
constructor(options: IConnectionOptions, remoteAuthority: string, clientId: string, reconnectionToken: string, protocol: PersistentProtocol) {
|
||||
super(options, reconnectionToken, protocol);
|
||||
this.client = this._register(new Client<RemoteAgentConnectionContext>(protocol, {
|
||||
remoteAuthority: remoteAuthority,
|
||||
clientId: clientId
|
||||
}));
|
||||
}
|
||||
|
||||
protected async _reconnect(options: ISimpleConnectionOptions): Promise<void> {
|
||||
await doConnectRemoteAgentManagement(options);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtensionHostPersistentConnection extends PersistentConnection {
|
||||
|
||||
private readonly _startArguments: IRemoteExtensionHostStartParams;
|
||||
public readonly debugPort: number | undefined;
|
||||
|
||||
constructor(options: IConnectionOptions, startArguments: IRemoteExtensionHostStartParams, reconnectionToken: string, protocol: PersistentProtocol, debugPort: number | undefined) {
|
||||
super(options, reconnectionToken, protocol);
|
||||
this._startArguments = startArguments;
|
||||
this.debugPort = debugPort;
|
||||
}
|
||||
|
||||
protected async _reconnect(options: ISimpleConnectionOptions): Promise<void> {
|
||||
await doConnectRemoteAgentExtensionHost(options, this._startArguments);
|
||||
}
|
||||
}
|
||||
|
||||
function getErrorFromMessage(msg: any): Error | null {
|
||||
if (msg && msg.type === 'error') {
|
||||
const error = new Error(`Connection error: ${msg.reason}`);
|
||||
(<any>error).code = 'VSCODE_CONNECTION_ERROR';
|
||||
return error;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { FileChangeType, FileDeleteOptions, FileOverwriteOptions, FileSystemProviderCapabilities, FileType, FileWriteOptions, IFileChange, IFileSystemProvider, IStat, IWatchOptions } from 'vs/platform/files/common/files';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
|
||||
export const REMOTE_FILE_SYSTEM_CHANNEL_NAME = 'remotefilesystem';
|
||||
|
||||
@@ -71,20 +72,17 @@ export class RemoteExtensionsFileSystemProvider extends Disposable implements IF
|
||||
|
||||
// --- forwarding calls
|
||||
|
||||
private static _asBuffer(data: Uint8Array): Buffer {
|
||||
return Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
||||
}
|
||||
|
||||
stat(resource: URI): Promise<IStat> {
|
||||
return this._channel.call('stat', [resource]);
|
||||
}
|
||||
|
||||
readFile(resource: URI): Promise<Uint8Array> {
|
||||
return this._channel.call('readFile', [resource]);
|
||||
async readFile(resource: URI): Promise<Uint8Array> {
|
||||
const buff = <VSBuffer>await this._channel.call('readFile', [resource]);
|
||||
return buff.buffer;
|
||||
}
|
||||
|
||||
writeFile(resource: URI, content: Uint8Array, opts: FileWriteOptions): Promise<void> {
|
||||
const contents = RemoteExtensionsFileSystemProvider._asBuffer(content);
|
||||
const contents = VSBuffer.wrap(content);
|
||||
return this._channel.call('writeFile', [resource, contents, opts]);
|
||||
}
|
||||
|
||||
12
src/vs/platform/remote/node/nodeWebSocketFactory.ts
Normal file
12
src/vs/platform/remote/node/nodeWebSocketFactory.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWebSocketFactory, IConnectCallback } from 'vs/platform/remote/common/remoteAgentConnection';
|
||||
|
||||
export const nodeWebSocketFactory = new class implements IWebSocketFactory {
|
||||
connect(host: string, port: number, query: string, callback: IConnectCallback): void {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
};
|
||||
@@ -1,60 +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 { Client, PersistentProtocol } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { RemoteAgentConnectionContext } from 'vs/platform/remote/common/remoteAgentEnvironment';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export interface IRemoteExtensionHostStartParams {
|
||||
language: string;
|
||||
debugId?: string;
|
||||
break?: boolean;
|
||||
port?: number | null;
|
||||
updatePort?: boolean;
|
||||
}
|
||||
|
||||
export async function connectRemoteAgentManagement(remoteAuthority: string, host: string, port: number, clientId: string, isBuilt: boolean): Promise<ManagementPersistentConnection> {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
|
||||
export async function connectRemoteAgentExtensionHost(host: string, port: number, startArguments: IRemoteExtensionHostStartParams, isBuilt: boolean): Promise<ExtensionHostPersistentConnection> {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
|
||||
abstract class PersistentConnection extends Disposable {
|
||||
|
||||
public readonly reconnectionToken: string;
|
||||
public readonly protocol: PersistentProtocol;
|
||||
|
||||
constructor(reconnectionToken: string, protocol: PersistentProtocol) {
|
||||
super();
|
||||
this.reconnectionToken = reconnectionToken;
|
||||
this.protocol = protocol;
|
||||
}
|
||||
}
|
||||
|
||||
export class ManagementPersistentConnection extends PersistentConnection {
|
||||
|
||||
public readonly client: Client<RemoteAgentConnectionContext>;
|
||||
|
||||
constructor(remoteAuthority: string, host: string, port: number, clientId: string, isBuilt: boolean, reconnectionToken: string, protocol: PersistentProtocol) {
|
||||
super(reconnectionToken, protocol);
|
||||
|
||||
this.client = this._register(new Client<RemoteAgentConnectionContext>(protocol, {
|
||||
remoteAuthority: remoteAuthority,
|
||||
clientId: clientId
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtensionHostPersistentConnection extends PersistentConnection {
|
||||
|
||||
public readonly debugPort: number | undefined;
|
||||
|
||||
constructor(host: string, port: number, startArguments: IRemoteExtensionHostStartParams, isBuilt: boolean, reconnectionToken: string, protocol: PersistentProtocol, debugPort: number | undefined) {
|
||||
super(reconnectionToken, protocol);
|
||||
this.debugPort = debugPort;
|
||||
}
|
||||
}
|
||||
@@ -259,7 +259,7 @@ export class StorageMainService extends Disposable implements IStorageMainServic
|
||||
return import('vscode-sqlite3').then(sqlite3 => {
|
||||
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const handleSuffixKey = (row, key: string, suffix: string) => {
|
||||
const handleSuffixKey = (row: any, key: string, suffix: string) => {
|
||||
if (endsWith(key, suffix.toLowerCase())) {
|
||||
const value: string = row.value.toString('utf16le');
|
||||
const normalizedKey = key.substring(0, key.length - suffix.length) + suffix;
|
||||
|
||||
@@ -61,7 +61,7 @@ export interface IColorRegistry {
|
||||
/**
|
||||
* Register a color to the registry.
|
||||
*/
|
||||
deregisterColor(id: string);
|
||||
deregisterColor(id: string): void;
|
||||
|
||||
/**
|
||||
* Get all color contributions
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { focusBorder, inputBackground, inputForeground, ColorIdentifier, selectForeground, selectBackground, selectListBackground, selectBorder, inputBorder, foreground, editorBackground, contrastBorder, inputActiveOptionBorder, listFocusBackground, listFocusForeground, listActiveSelectionBackground, listActiveSelectionForeground, listInactiveSelectionForeground, listInactiveSelectionBackground, listInactiveFocusBackground, listHoverBackground, listHoverForeground, listDropBackground, pickerGroupBorder, pickerGroupForeground, widgetShadow, inputValidationInfoBorder, inputValidationInfoBackground, inputValidationWarningBorder, inputValidationWarningBackground, inputValidationErrorBorder, inputValidationErrorBackground, activeContrastBorder, buttonForeground, buttonBackground, buttonHoverBackground, ColorFunction, badgeBackground, badgeForeground, progressBarBackground, breadcrumbsForeground, breadcrumbsFocusForeground, breadcrumbsActiveSelectionForeground, breadcrumbsBackground, editorWidgetBorder, inputValidationInfoForeground, inputValidationWarningForeground, inputValidationErrorForeground, menuForeground, menuBackground, menuSelectionForeground, menuSelectionBackground, menuSelectionBorder, menuBorder, menuSeparatorBackground, darken, listFilterWidgetOutline, listFilterWidgetNoMatchesOutline, listFilterWidgetBackground, editorWidgetBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
@@ -329,3 +329,24 @@ export const defaultMenuStyles = <IMenuStyleOverrides>{
|
||||
export function attachMenuStyler(widget: IThemable, themeService: IThemeService, style?: IMenuStyleOverrides): IDisposable {
|
||||
return attachStyler(themeService, { ...defaultMenuStyles, ...style }, widget);
|
||||
}
|
||||
|
||||
export interface IDialogStyleOverrides extends IButtonStyleOverrides {
|
||||
dialogForeground?: ColorIdentifier;
|
||||
dialogBackground?: ColorIdentifier;
|
||||
dialogShadow?: ColorIdentifier;
|
||||
}
|
||||
|
||||
export const defaultDialogStyles = <IDialogStyleOverrides>{
|
||||
dialogBackground: editorWidgetBackground,
|
||||
dialogForeground: foreground,
|
||||
dialogShadow: widgetShadow,
|
||||
buttonForeground: buttonForeground,
|
||||
buttonBackground: buttonBackground,
|
||||
buttonHoverBackground: buttonHoverBackground,
|
||||
buttonBorder: contrastBorder
|
||||
};
|
||||
|
||||
|
||||
export function attachDialogStyler(widget: IThemable, themeService: IThemeService, style?: IDialogStyleOverrides): IDisposable {
|
||||
return attachStyler(themeService, { ...defaultDialogStyles, ...style }, widget);
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ export class Win32UpdateService extends AbstractUpdateService {
|
||||
}
|
||||
|
||||
private async cleanup(exceptVersion: string | null = null): Promise<any> {
|
||||
const filter = exceptVersion ? one => !(new RegExp(`${product.quality}-${exceptVersion}\\.exe$`).test(one)) : () => true;
|
||||
const filter = exceptVersion ? (one: string) => !(new RegExp(`${product.quality}-${exceptVersion}\\.exe$`).test(one)) : () => true;
|
||||
|
||||
const cachePath = await this.cachePath;
|
||||
const versions = await pfs.readdir(cachePath);
|
||||
|
||||
@@ -84,6 +84,7 @@ export interface SaveDialogOptions {
|
||||
|
||||
export interface INewWindowOptions {
|
||||
remoteAuthority?: string;
|
||||
reuseWindow?: boolean;
|
||||
}
|
||||
|
||||
export interface IDevToolsOptions {
|
||||
@@ -149,9 +150,8 @@ export interface IWindowsService {
|
||||
toggleSharedProcess(): Promise<void>;
|
||||
|
||||
// Global methods
|
||||
openWindow(windowId: number, uris: IURIToOpen[], options?: IOpenSettings): Promise<void>;
|
||||
openWindow(windowId: number, uris: IURIToOpen[], options: IOpenSettings): Promise<void>;
|
||||
openNewWindow(options?: INewWindowOptions): Promise<void>;
|
||||
showWindow(windowId: number): Promise<void>;
|
||||
getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]>;
|
||||
getWindowCount(): Promise<number>;
|
||||
log(severity: string, ...messages: string[]): Promise<void>;
|
||||
@@ -183,6 +183,7 @@ export interface IOpenSettings {
|
||||
diffMode?: boolean;
|
||||
addMode?: boolean;
|
||||
noRecentEntry?: boolean;
|
||||
waitMarkerFileURI?: URI;
|
||||
args?: ParsedArgs;
|
||||
}
|
||||
|
||||
@@ -228,7 +229,6 @@ export interface IWindowService {
|
||||
unmaximizeWindow(): Promise<void>;
|
||||
minimizeWindow(): Promise<void>;
|
||||
onWindowTitleDoubleClick(): Promise<void>;
|
||||
show(): Promise<void>;
|
||||
showMessageBox(options: MessageBoxOptions): Promise<IMessageBoxResult>;
|
||||
showSaveDialog(options: SaveDialogOptions): Promise<string>;
|
||||
showOpenDialog(options: OpenDialogOptions): Promise<string[]>;
|
||||
|
||||
@@ -98,7 +98,7 @@ export class WindowService extends Disposable implements IWindowService {
|
||||
return this.windowsService.enterWorkspace(this.windowId, path);
|
||||
}
|
||||
|
||||
openWindow(uris: IURIToOpen[], options?: IOpenSettings): Promise<void> {
|
||||
openWindow(uris: IURIToOpen[], options: IOpenSettings = {}): Promise<void> {
|
||||
if (!!this.configuration.remoteAuthority) {
|
||||
uris.forEach(u => u.label = u.label || this.getRecentLabel(u, !!(options && options.forceOpenWorkspaceAsFile)));
|
||||
}
|
||||
@@ -153,10 +153,6 @@ export class WindowService extends Disposable implements IWindowService {
|
||||
return this.windowsService.setDocumentEdited(this.windowId, flag);
|
||||
}
|
||||
|
||||
show(): Promise<void> {
|
||||
return this.windowsService.showWindow(this.windowId);
|
||||
}
|
||||
|
||||
showMessageBox(options: Electron.MessageBoxOptions): Promise<IMessageBoxResult> {
|
||||
return this.windowsService.showMessageBox(this.windowId, options);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, CrashReporterStartOptions, IMessageBoxResult, MessageBoxOptions, SaveDialogOptions, OpenDialogOptions, IDevToolsOptions, INewWindowOptions, IURIToOpen } from 'vs/platform/windows/common/windows';
|
||||
import { IWindowsService, INativeOpenDialogOptions, IEnterWorkspaceResult, CrashReporterStartOptions, IMessageBoxResult, MessageBoxOptions, SaveDialogOptions, OpenDialogOptions, IDevToolsOptions, INewWindowOptions, IURIToOpen, IOpenSettings } from 'vs/platform/windows/common/windows';
|
||||
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, reviveWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { IRecentlyOpened, IRecent, isRecentWorkspace } from 'vs/platform/history/common/history';
|
||||
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
|
||||
@@ -186,7 +186,7 @@ export class WindowsService implements IWindowsService {
|
||||
return this.channel.call('toggleSharedProcess');
|
||||
}
|
||||
|
||||
openWindow(windowId: number, uris: IURIToOpen[], options?: { forceNewWindow?: boolean, forceReuseWindow?: boolean, forceOpenWorkspaceAsFile?: boolean, args?: ParsedArgs }): Promise<void> {
|
||||
openWindow(windowId: number, uris: IURIToOpen[], options: IOpenSettings): Promise<void> {
|
||||
return this.channel.call('openWindow', [windowId, uris, options]);
|
||||
}
|
||||
|
||||
@@ -194,10 +194,6 @@ export class WindowsService implements IWindowsService {
|
||||
return this.channel.call('openNewWindow', options);
|
||||
}
|
||||
|
||||
showWindow(windowId: number): Promise<void> {
|
||||
return this.channel.call('showWindow', windowId);
|
||||
}
|
||||
|
||||
getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> {
|
||||
return this.channel.call<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]>('getWindows').then(result => {
|
||||
for (const win of result) {
|
||||
|
||||
@@ -125,6 +125,7 @@ export interface IOpenConfiguration {
|
||||
readonly cli: ParsedArgs;
|
||||
readonly userEnv?: IProcessEnvironment;
|
||||
readonly urisToOpen?: IURIToOpen[];
|
||||
readonly waitMarkerFileURI?: URI;
|
||||
readonly preferNewWindow?: boolean;
|
||||
readonly forceNewWindow?: boolean;
|
||||
readonly forceNewTabbedWindow?: boolean;
|
||||
|
||||
@@ -218,7 +218,11 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
|
||||
async focusWindow(windowId: number): Promise<void> {
|
||||
this.logService.trace('windowsService#focusWindow', windowId);
|
||||
|
||||
return this.withWindow(windowId, codeWindow => codeWindow.win.focus());
|
||||
if (isMacintosh) {
|
||||
return this.withWindow(windowId, codeWindow => codeWindow.win.show());
|
||||
} else {
|
||||
return this.withWindow(windowId, codeWindow => codeWindow.win.focus());
|
||||
}
|
||||
}
|
||||
|
||||
async closeWindow(windowId: number): Promise<void> {
|
||||
@@ -273,7 +277,7 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
|
||||
});
|
||||
}
|
||||
|
||||
async openWindow(windowId: number, urisToOpen: IURIToOpen[], options: IOpenSettings = {}): Promise<void> {
|
||||
async openWindow(windowId: number, urisToOpen: IURIToOpen[], options: IOpenSettings): Promise<void> {
|
||||
this.logService.trace('windowsService#openWindow');
|
||||
if (!urisToOpen || !urisToOpen.length) {
|
||||
return undefined;
|
||||
@@ -289,7 +293,8 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
|
||||
forceOpenWorkspaceAsFile: options.forceOpenWorkspaceAsFile,
|
||||
diffMode: options.diffMode,
|
||||
addMode: options.addMode,
|
||||
noRecentEntry: options.noRecentEntry
|
||||
noRecentEntry: options.noRecentEntry,
|
||||
waitMarkerFileURI: options.waitMarkerFileURI
|
||||
});
|
||||
}
|
||||
|
||||
@@ -299,12 +304,6 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
|
||||
this.windowsMainService.openNewWindow(OpenContext.API, options);
|
||||
}
|
||||
|
||||
async showWindow(windowId: number): Promise<void> {
|
||||
this.logService.trace('windowsService#showWindow', windowId);
|
||||
|
||||
return this.withWindow(windowId, codeWindow => codeWindow.win.show());
|
||||
}
|
||||
|
||||
async getWindows(): Promise<{ id: number; workspace?: IWorkspaceIdentifier; folderUri?: ISingleFolderWorkspaceIdentifier; title: string; filename?: string; }[]> {
|
||||
this.logService.trace('windowsService#getWindows');
|
||||
|
||||
@@ -466,4 +465,4 @@ export class WindowsService implements IWindowsService, IURLHandler, IDisposable
|
||||
dispose(): void {
|
||||
this.disposables = dispose(this.disposables);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IServerChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IWindowsService, IURIToOpen } from 'vs/platform/windows/common/windows';
|
||||
import { IWindowsService, IURIToOpen, IOpenSettings } from 'vs/platform/windows/common/windows';
|
||||
import { reviveWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IRecent, isRecentFile, isRecentFolder } from 'vs/platform/history/common/history';
|
||||
@@ -86,9 +86,14 @@ export class WindowsChannel implements IServerChannel {
|
||||
case 'minimizeWindow': return this.service.minimizeWindow(arg);
|
||||
case 'onWindowTitleDoubleClick': return this.service.onWindowTitleDoubleClick(arg);
|
||||
case 'setDocumentEdited': return this.service.setDocumentEdited(arg[0], arg[1]);
|
||||
case 'openWindow': return this.service.openWindow(arg[0], arg[1] ? (<IURIToOpen[]>arg[1]).map(r => { r.uri = URI.revive(r.uri); return r; }) : arg[1], arg[2]);
|
||||
case 'openWindow': {
|
||||
const urisToOpen: IURIToOpen[] = arg[1];
|
||||
const options: IOpenSettings = arg[2];
|
||||
urisToOpen.forEach(r => { r.uri = URI.revive(r.uri); return r; });
|
||||
options.waitMarkerFileURI = options.waitMarkerFileURI && URI.revive(options.waitMarkerFileURI);
|
||||
return this.service.openWindow(arg[0], urisToOpen, options);
|
||||
}
|
||||
case 'openNewWindow': return this.service.openNewWindow(arg);
|
||||
case 'showWindow': return this.service.showWindow(arg);
|
||||
case 'getWindows': return this.service.getWindows();
|
||||
case 'getWindowCount': return this.service.getWindowCount();
|
||||
case 'relaunch': return this.service.relaunch(arg[0]);
|
||||
|
||||
Reference in New Issue
Block a user