mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-10 02:02:35 -05:00
Merge from vscode 5b9869eb02fa4c96205a74d05cad9164dfd06d60 (#5607)
This commit is contained in:
@@ -12,7 +12,7 @@ import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files';
|
||||
import { ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels';
|
||||
import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, IConfigurationFileService, MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, IConfigurationFileService, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { IStoredWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService';
|
||||
import { WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
@@ -45,7 +45,7 @@ export class RemoteUserConfiguration extends Disposable {
|
||||
this._userConfiguration = this._cachedConfiguration = new CachedUserConfiguration(remoteAuthority, configurationCache);
|
||||
remoteAgentService.getEnvironment().then(async environment => {
|
||||
if (environment) {
|
||||
const userConfiguration = this._register(new UserConfiguration(environment.settingsPath, MACHINE_SCOPES, this._configurationFileService));
|
||||
const userConfiguration = this._register(new UserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService));
|
||||
this._register(userConfiguration.onDidChangeConfiguration(configurationModel => this.onDidUserConfigurationChange(configurationModel)));
|
||||
this._userConfigurationInitializationPromise = userConfiguration.initialize();
|
||||
const configurationModel = await this._userConfigurationInitializationPromise;
|
||||
|
||||
@@ -15,7 +15,7 @@ import { isLinux } from 'vs/base/common/platform';
|
||||
import { ConfigurationChangeEvent, ConfigurationModel, DefaultConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
|
||||
import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { Configuration, WorkspaceConfigurationChangeEvent, AllKeysConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels';
|
||||
import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, IConfigurationFileService, machineSettingsSchemaId } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, IConfigurationFileService, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES } from 'vs/workbench/services/configuration/common/configuration';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceInitializationPayload, isSingleFolderWorkspaceInitializationPayload, ISingleFolderWorkspaceInitializationPayload, IEmptyWorkspaceInitializationPayload, useSlashForPath, getStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
|
||||
@@ -74,7 +74,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
|
||||
this.defaultConfiguration = new DefaultConfigurationModel();
|
||||
this.configurationCache = configurationCache;
|
||||
if (userSettingsResource) {
|
||||
this.localUserConfiguration = this._register(new UserConfiguration(userSettingsResource, undefined, configurationFileService));
|
||||
this.localUserConfiguration = this._register(new UserConfiguration(userSettingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, configurationFileService));
|
||||
this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration)));
|
||||
}
|
||||
if (remoteAuthority) {
|
||||
@@ -515,14 +515,16 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
|
||||
}, {});
|
||||
};
|
||||
|
||||
const unsupportedApplicationSettings = convertToNotSuggestedProperties(applicationSettings.properties, localize('unsupportedApplicationSetting', "This setting can be applied only in application user settings"));
|
||||
const unsupportedMachineSettings = convertToNotSuggestedProperties(machineSettings.properties, localize('unsupportedMachineSetting', "This setting can be applied only in user settings"));
|
||||
const unsupportedRemoteMachineSettings = convertToNotSuggestedProperties(machineSettings.properties, localize('unsupportedRemoteMachineSetting', "This setting can be applied only in remote machine settings"));
|
||||
const allSettingsSchema: IJSONSchema = { properties: allSettings.properties, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' };
|
||||
const unsupportedApplicationSettings = convertToNotSuggestedProperties(applicationSettings.properties, localize('unsupportedApplicationSetting', "This setting can be applied only in application user Settings"));
|
||||
const unsupportedMachineSettings = convertToNotSuggestedProperties(machineSettings.properties, localize('unsupportedMachineSetting', "This setting can be applied only in user Settings"));
|
||||
const userSettingsSchema: IJSONSchema = this.remoteUserConfiguration ? { properties: { ...applicationSettings.properties, ...unsupportedRemoteMachineSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' } : allSettingsSchema;
|
||||
const machineSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' };
|
||||
const workspaceSettingsSchema: IJSONSchema = { properties: { ...unsupportedApplicationSettings, ...unsupportedMachineSettings, ...windowSettings.properties, ...resourceSettings.properties }, patternProperties: allSettings.patternProperties, additionalProperties: false, errorMessage: 'Unknown configuration setting' };
|
||||
|
||||
jsonRegistry.registerSchema(defaultSettingsSchemaId, allSettingsSchema);
|
||||
jsonRegistry.registerSchema(userSettingsSchemaId, allSettingsSchema);
|
||||
jsonRegistry.registerSchema(userSettingsSchemaId, userSettingsSchema);
|
||||
jsonRegistry.registerSchema(machineSettingsSchemaId, machineSettingsSchema);
|
||||
|
||||
if (WorkbenchState.WORKSPACE === this.getWorkbenchState()) {
|
||||
|
||||
@@ -20,7 +20,8 @@ export const workspaceSettingsSchemaId = 'vscode://schemas/settings/workspace';
|
||||
export const folderSettingsSchemaId = 'vscode://schemas/settings/folder';
|
||||
export const launchSchemaId = 'vscode://schemas/launch';
|
||||
|
||||
export const MACHINE_SCOPES = [ConfigurationScope.MACHINE, ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE];
|
||||
export const LOCAL_MACHINE_SCOPES = [ConfigurationScope.APPLICATION, ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE];
|
||||
export const REMOTE_MACHINE_SCOPES = [ConfigurationScope.MACHINE, ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE];
|
||||
export const WORKSPACE_SCOPES = [ConfigurationScope.WINDOW, ConfigurationScope.RESOURCE];
|
||||
export const FOLDER_SCOPES = [ConfigurationScope.RESOURCE];
|
||||
|
||||
|
||||
@@ -268,6 +268,14 @@ suite('WorkspaceConfigurationService - Remote Folder', () => {
|
||||
// return promise;
|
||||
// });
|
||||
|
||||
test('machine settings in local user settings does not override defaults', async () => {
|
||||
fs.writeFileSync(globalSettingsFile, '{ "configurationService.remote.machineSetting": "globalValue" }');
|
||||
registerRemoteFileSystemProvider();
|
||||
resolveRemoteEnvironment();
|
||||
await initialize();
|
||||
assert.equal(testObject.getValue('configurationService.remote.machineSetting'), 'isSet');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function getWorkspaceId(configPath: URI): string {
|
||||
|
||||
@@ -172,7 +172,7 @@ class NativeContextMenuService extends Disposable implements IContextMenuService
|
||||
}
|
||||
}
|
||||
|
||||
private runAction(actionRunner: IActionRunner, actionToRun: IAction, delegate: IContextMenuDelegate, event: IContextMenuEvent): void {
|
||||
private async runAction(actionRunner: IActionRunner, actionToRun: IAction, delegate: IContextMenuDelegate, event: IContextMenuEvent): Promise<void> {
|
||||
/* __GDPR__
|
||||
"workbenchActionExecuted" : {
|
||||
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
@@ -182,9 +182,15 @@ class NativeContextMenuService extends Disposable implements IContextMenuService
|
||||
this.telemetryService.publicLog('workbenchActionExecuted', { id: actionToRun.id, from: 'contextMenu' });
|
||||
|
||||
const context = delegate.getActionsContext ? delegate.getActionsContext(event) : event;
|
||||
const res = actionRunner.run(actionToRun, context) || Promise.resolve(null);
|
||||
|
||||
res.then(undefined, e => this.notificationService.error(e));
|
||||
const runnable = actionRunner.run(actionToRun, context);
|
||||
if (runnable) {
|
||||
try {
|
||||
await runnable;
|
||||
} catch (error) {
|
||||
this.notificationService.error(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,17 +78,16 @@ class NativeDialogService implements IDialogService {
|
||||
sharedProcessService.registerChannel('dialog', new DialogChannel(this));
|
||||
}
|
||||
|
||||
confirm(confirmation: IConfirmation): Promise<IConfirmationResult> {
|
||||
async confirm(confirmation: IConfirmation): Promise<IConfirmationResult> {
|
||||
this.logService.trace('DialogService#confirm', confirmation.message);
|
||||
|
||||
const { options, buttonIndexMap } = this.massageMessageBoxOptions(this.getConfirmOptions(confirmation));
|
||||
|
||||
return this.windowService.showMessageBox(options).then(result => {
|
||||
return {
|
||||
confirmed: buttonIndexMap[result.button] === 0 ? true : false,
|
||||
checkboxChecked: result.checkboxChecked
|
||||
};
|
||||
});
|
||||
const result = await this.windowService.showMessageBox(options);
|
||||
return {
|
||||
confirmed: buttonIndexMap[result.button] === 0 ? true : false,
|
||||
checkboxChecked: result.checkboxChecked
|
||||
};
|
||||
}
|
||||
|
||||
private getConfirmOptions(confirmation: IConfirmation): Electron.MessageBoxOptions {
|
||||
@@ -128,7 +127,7 @@ class NativeDialogService implements IDialogService {
|
||||
return opts;
|
||||
}
|
||||
|
||||
show(severity: Severity, message: string, buttons: string[], dialogOptions?: IDialogOptions): Promise<number> {
|
||||
async show(severity: Severity, message: string, buttons: string[], dialogOptions?: IDialogOptions): Promise<number> {
|
||||
this.logService.trace('DialogService#show', message);
|
||||
|
||||
const { options, buttonIndexMap } = this.massageMessageBoxOptions({
|
||||
@@ -139,7 +138,8 @@ class NativeDialogService implements IDialogService {
|
||||
detail: dialogOptions ? dialogOptions.detail : undefined
|
||||
});
|
||||
|
||||
return this.windowService.showMessageBox(options).then(result => buttonIndexMap[result.button]);
|
||||
const result = await this.windowService.showMessageBox(options);
|
||||
return buttonIndexMap[result.button];
|
||||
}
|
||||
|
||||
private massageMessageBoxOptions(options: Electron.MessageBoxOptions): IMassagedMessageBoxOptions {
|
||||
|
||||
@@ -62,17 +62,16 @@ export class CodeEditorService extends CodeEditorServiceImpl {
|
||||
return this.doOpenCodeEditor(input, source, sideBySide);
|
||||
}
|
||||
|
||||
private doOpenCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Promise<ICodeEditor | null> {
|
||||
return this.editorService.openEditor(input, sideBySide ? SIDE_GROUP : ACTIVE_GROUP).then(control => {
|
||||
if (control) {
|
||||
const widget = control.getControl();
|
||||
if (isCodeEditor(widget)) {
|
||||
return widget;
|
||||
}
|
||||
private async doOpenCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Promise<ICodeEditor | null> {
|
||||
const control = await this.editorService.openEditor(input, sideBySide ? SIDE_GROUP : ACTIVE_GROUP);
|
||||
if (control) {
|
||||
const widget = control.getControl();
|
||||
if (isCodeEditor(widget)) {
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -331,7 +331,7 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
||||
|
||||
openEditors(editors: IEditorInputWithOptions[], group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditor[]>;
|
||||
openEditors(editors: IResourceEditor[], group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditor[]>;
|
||||
openEditors(editors: Array<IEditorInputWithOptions | IResourceEditor>, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditor[]> {
|
||||
async openEditors(editors: Array<IEditorInputWithOptions | IResourceEditor>, group?: IEditorGroup | GroupIdentifier | SIDE_GROUP_TYPE | ACTIVE_GROUP_TYPE): Promise<IEditor[]> {
|
||||
|
||||
// Convert to typed editors and options
|
||||
const typedEditors: IEditorInputWithOptions[] = [];
|
||||
@@ -367,7 +367,9 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
||||
result.push(group.openEditors(editorsWithOptions));
|
||||
});
|
||||
|
||||
return Promise.all(result).then(editors => coalesce(editors));
|
||||
const openedEditors = await Promise.all(result);
|
||||
|
||||
return coalesce(openedEditors);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -6,9 +6,48 @@
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
|
||||
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { isUIExtension as _isUIExtension } from 'vs/platform/extensions/node/extensionsUtil';
|
||||
import { getGalleryExtensionId, areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import product from 'vs/platform/product/node/product';
|
||||
|
||||
export function isUIExtension(manifest: IExtensionManifest, configurationService: IConfigurationService): boolean {
|
||||
const uiExtensionPoints = ExtensionsRegistry.getExtensionPoints().filter(e => e.defaultExtensionKind !== 'workspace').map(e => e.name);
|
||||
return _isUIExtension(manifest, uiExtensionPoints, configurationService);
|
||||
const uiContributions = ExtensionsRegistry.getExtensionPoints().filter(e => e.defaultExtensionKind !== 'workspace').map(e => e.name);
|
||||
const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name);
|
||||
const extensionKind = getExtensionKind(manifest, configurationService);
|
||||
switch (extensionKind) {
|
||||
case 'ui': return true;
|
||||
case 'workspace': return false;
|
||||
default: {
|
||||
// Tagged as UI extension in product
|
||||
if (isNonEmptyArray(product.uiExtensions) && product.uiExtensions.some(id => areSameExtensions({ id }, { id: extensionId }))) {
|
||||
return true;
|
||||
}
|
||||
// Not an UI extension if it has main
|
||||
if (manifest.main) {
|
||||
return false;
|
||||
}
|
||||
// Not an UI extension if it has dependencies or an extension pack
|
||||
if (isNonEmptyArray(manifest.extensionDependencies) || isNonEmptyArray(manifest.extensionPack)) {
|
||||
return false;
|
||||
}
|
||||
if (manifest.contributes) {
|
||||
// Not an UI extension if it has no ui contributions
|
||||
if (!uiContributions.length || Object.keys(manifest.contributes).some(contribution => uiContributions.indexOf(contribution) === -1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getExtensionKind(manifest: IExtensionManifest, configurationService: IConfigurationService): string | undefined {
|
||||
const extensionId = getGalleryExtensionId(manifest.publisher, manifest.name);
|
||||
const configuredExtensionKinds = configurationService.getValue<{ [key: string]: string }>('remote.extensionKind') || {};
|
||||
for (const id of Object.keys(configuredExtensionKinds)) {
|
||||
if (areSameExtensions({ id: extensionId }, { id })) {
|
||||
return configuredExtensionKinds[id];
|
||||
}
|
||||
}
|
||||
return manifest.extensionKind;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
import { IDiskFileChange, normalizeFileChanges } from 'vs/workbench/services/files/node/watcher/watcher';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { statLink, readlink } from 'vs/base/node/pfs';
|
||||
import { statLink } from 'vs/base/node/pfs';
|
||||
import { realpath } from 'vs/base/node/extpath';
|
||||
import { watchFolder, watchFile, CHANGE_BUFFER_DELAY } from 'vs/base/node/watcher';
|
||||
import { FileChangeType } from 'vs/platform/files/common/files';
|
||||
import { ThrottledDelayer } from 'vs/base/common/async';
|
||||
@@ -40,7 +41,7 @@ export class FileWatcher extends Disposable {
|
||||
let pathToWatch = this.path;
|
||||
if (isSymbolicLink) {
|
||||
try {
|
||||
pathToWatch = await readlink(pathToWatch);
|
||||
pathToWatch = await realpath(pathToWatch);
|
||||
} catch (error) {
|
||||
this.onError(error);
|
||||
}
|
||||
|
||||
@@ -71,9 +71,9 @@ export class IntegrityServiceImpl implements IIntegrityService {
|
||||
|
||||
this.isPure().then(r => {
|
||||
if (r.isPure) {
|
||||
// all is good
|
||||
return;
|
||||
return; // all is good
|
||||
}
|
||||
|
||||
this._prompt();
|
||||
});
|
||||
}
|
||||
@@ -106,29 +106,25 @@ export class IntegrityServiceImpl implements IIntegrityService {
|
||||
return this._isPurePromise;
|
||||
}
|
||||
|
||||
private _isPure(): Promise<IntegrityTestResult> {
|
||||
private async _isPure(): Promise<IntegrityTestResult> {
|
||||
const expectedChecksums = product.checksums || {};
|
||||
|
||||
return this.lifecycleService.when(LifecyclePhase.Eventually).then(() => {
|
||||
let asyncResults: Promise<ChecksumPair>[] = Object.keys(expectedChecksums).map((filename) => {
|
||||
return this._resolve(filename, expectedChecksums[filename]);
|
||||
});
|
||||
await this.lifecycleService.when(LifecyclePhase.Eventually);
|
||||
|
||||
return Promise.all(asyncResults).then<IntegrityTestResult>((allResults) => {
|
||||
let isPure = true;
|
||||
for (let i = 0, len = allResults.length; i < len; i++) {
|
||||
if (!allResults[i].isPure) {
|
||||
isPure = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const allResults = await Promise.all(Object.keys(expectedChecksums).map(filename => this._resolve(filename, expectedChecksums[filename])));
|
||||
|
||||
return {
|
||||
isPure: isPure,
|
||||
proof: allResults
|
||||
};
|
||||
});
|
||||
});
|
||||
let isPure = true;
|
||||
for (let i = 0, len = allResults.length; i < len; i++) {
|
||||
if (!allResults[i].isPure) {
|
||||
isPure = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isPure: isPure,
|
||||
proof: allResults
|
||||
};
|
||||
}
|
||||
|
||||
private _resolve(filename: string, expected: string): Promise<ChecksumPair> {
|
||||
|
||||
@@ -208,7 +208,8 @@ export class ScopedProgressService extends ScopedService implements IProgressSer
|
||||
};
|
||||
}
|
||||
|
||||
showWhile(promise: Promise<any>, delay?: number): Promise<void> {
|
||||
async showWhile(promise: Promise<any>, delay?: number): Promise<void> {
|
||||
|
||||
// Join with existing running promise to ensure progress is accurate
|
||||
if (this.progressState.type === ProgressState.Type.While) {
|
||||
promise = Promise.all([promise, this.progressState.whilePromise]);
|
||||
@@ -217,24 +218,25 @@ export class ScopedProgressService extends ScopedService implements IProgressSer
|
||||
// Keep Promise in State
|
||||
this.progressState = new ProgressState.While(promise, delay || 0, Date.now());
|
||||
|
||||
let stop = () => {
|
||||
try {
|
||||
this.doShowWhile(delay);
|
||||
|
||||
// If this is not the last promise in the list of joined promises, return early
|
||||
if (this.progressState.type === ProgressState.Type.While && this.progressState.whilePromise !== promise) {
|
||||
return;
|
||||
await promise;
|
||||
} catch (error) {
|
||||
// ignore
|
||||
} finally {
|
||||
|
||||
// If this is not the last promise in the list of joined promises, skip this
|
||||
if (this.progressState.type !== ProgressState.Type.While || this.progressState.whilePromise === promise) {
|
||||
|
||||
// The while promise is either null or equal the promise we last hooked on
|
||||
this.progressState = ProgressState.None;
|
||||
|
||||
if (this.isActive) {
|
||||
this.progressbar.stop().hide();
|
||||
}
|
||||
}
|
||||
|
||||
// The while promise is either null or equal the promise we last hooked on
|
||||
this.progressState = ProgressState.None;
|
||||
|
||||
if (this.isActive) {
|
||||
this.progressbar.stop().hide();
|
||||
}
|
||||
};
|
||||
|
||||
this.doShowWhile(delay);
|
||||
|
||||
return promise.then(stop, stop);
|
||||
}
|
||||
}
|
||||
|
||||
private doShowWhile(delay?: number): void {
|
||||
@@ -280,13 +282,15 @@ export class ProgressService implements IProgressService {
|
||||
};
|
||||
}
|
||||
|
||||
showWhile(promise: Promise<any>, delay?: number): Promise<void> {
|
||||
const stop = () => {
|
||||
async showWhile(promise: Promise<any>, delay?: number): Promise<void> {
|
||||
try {
|
||||
this.progressbar.infinite().show(delay);
|
||||
|
||||
await promise;
|
||||
} catch (error) {
|
||||
// ignore
|
||||
} finally {
|
||||
this.progressbar.stop().hide();
|
||||
};
|
||||
|
||||
this.progressbar.infinite().show(delay);
|
||||
|
||||
return promise.then(stop, stop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,28 +34,28 @@ export class RemoteExtensionEnvironmentChannelClient {
|
||||
|
||||
constructor(private channel: IChannel) { }
|
||||
|
||||
getEnvironmentData(remoteAuthority: string, extensionDevelopmentPath?: URI[]): Promise<IRemoteAgentEnvironment> {
|
||||
async getEnvironmentData(remoteAuthority: string, extensionDevelopmentPath?: URI[]): Promise<IRemoteAgentEnvironment> {
|
||||
const args: IGetEnvironmentDataArguments = {
|
||||
language: platform.language,
|
||||
remoteAuthority,
|
||||
extensionDevelopmentPath
|
||||
};
|
||||
return this.channel.call<IRemoteAgentEnvironmentDTO>('getEnvironmentData', args)
|
||||
.then((data: IRemoteAgentEnvironmentDTO): IRemoteAgentEnvironment => {
|
||||
return {
|
||||
pid: data.pid,
|
||||
appRoot: URI.revive(data.appRoot),
|
||||
appSettingsHome: URI.revive(data.appSettingsHome),
|
||||
settingsPath: URI.revive(data.settingsPath),
|
||||
logsPath: URI.revive(data.logsPath),
|
||||
extensionsPath: URI.revive(data.extensionsPath),
|
||||
extensionHostLogsPath: URI.revive(data.extensionHostLogsPath),
|
||||
globalStorageHome: URI.revive(data.globalStorageHome),
|
||||
userHome: URI.revive(data.userHome),
|
||||
extensions: data.extensions.map(ext => { (<any>ext).extensionLocation = URI.revive(ext.extensionLocation); return ext; }),
|
||||
os: data.os
|
||||
};
|
||||
});
|
||||
|
||||
const data = await this.channel.call<IRemoteAgentEnvironmentDTO>('getEnvironmentData', args);
|
||||
|
||||
return {
|
||||
pid: data.pid,
|
||||
appRoot: URI.revive(data.appRoot),
|
||||
appSettingsHome: URI.revive(data.appSettingsHome),
|
||||
settingsPath: URI.revive(data.settingsPath),
|
||||
logsPath: URI.revive(data.logsPath),
|
||||
extensionsPath: URI.revive(data.extensionsPath),
|
||||
extensionHostLogsPath: URI.revive(data.extensionHostLogsPath),
|
||||
globalStorageHome: URI.revive(data.globalStorageHome),
|
||||
userHome: URI.revive(data.userHome),
|
||||
extensions: data.extensions.map(ext => { (<any>ext).extensionLocation = URI.revive(ext.extensionLocation); return ext; }),
|
||||
os: data.os
|
||||
};
|
||||
}
|
||||
|
||||
getDiagnosticInfo(options: IDiagnosticInfoOptions): Promise<IDiagnosticInfo> {
|
||||
|
||||
@@ -31,7 +31,7 @@ class ResourceModelCollection extends ReferenceCollection<Promise<ITextEditorMod
|
||||
super();
|
||||
}
|
||||
|
||||
createReferencedObject(key: string, skipActivateProvider?: boolean): Promise<ITextEditorModel> {
|
||||
async createReferencedObject(key: string, skipActivateProvider?: boolean): Promise<ITextEditorModel> {
|
||||
this.modelsToDispose.delete(key);
|
||||
|
||||
const resource = URI.parse(key);
|
||||
@@ -43,15 +43,19 @@ class ResourceModelCollection extends ReferenceCollection<Promise<ITextEditorMod
|
||||
|
||||
// Virtual documents
|
||||
if (this.providers[resource.scheme]) {
|
||||
return this.resolveTextModelContent(key).then(() => this.instantiationService.createInstance(ResourceEditorModel, resource));
|
||||
await this.resolveTextModelContent(key);
|
||||
|
||||
return this.instantiationService.createInstance(ResourceEditorModel, resource);
|
||||
}
|
||||
|
||||
// Either unknown schema, or not yet registered, try to activate
|
||||
if (!skipActivateProvider) {
|
||||
return this.fileService.activateProvider(resource.scheme).then(() => this.createReferencedObject(key, true));
|
||||
await this.fileService.activateProvider(resource.scheme);
|
||||
|
||||
return this.createReferencedObject(key, true);
|
||||
}
|
||||
|
||||
return Promise.reject(new Error('resource is not available'));
|
||||
throw new Error('resource is not available');
|
||||
}
|
||||
|
||||
destroyReferencedObject(key: string, modelPromise: Promise<ITextEditorModel>): void {
|
||||
@@ -101,18 +105,17 @@ class ResourceModelCollection extends ReferenceCollection<Promise<ITextEditorMod
|
||||
return this.providers[scheme] !== undefined;
|
||||
}
|
||||
|
||||
private resolveTextModelContent(key: string): Promise<ITextModel> {
|
||||
private async resolveTextModelContent(key: string): Promise<ITextModel> {
|
||||
const resource = URI.parse(key);
|
||||
const providers = this.providers[resource.scheme] || [];
|
||||
const factories = providers.map(p => () => Promise.resolve(p.provideTextContent(resource)));
|
||||
|
||||
return first(factories).then(model => {
|
||||
if (!model) {
|
||||
return Promise.reject(new Error('resource is not available'));
|
||||
}
|
||||
const model = await first(factories);
|
||||
if (!model) {
|
||||
throw new Error('resource is not available');
|
||||
}
|
||||
|
||||
return model;
|
||||
});
|
||||
return model;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,14 +134,16 @@ export class TextModelResolverService implements ITextModelService {
|
||||
}
|
||||
|
||||
createModelReference(resource: URI): Promise<IReference<IResolvedTextEditorModel>> {
|
||||
return this._createModelReference(resource);
|
||||
return this.doCreateModelReference(resource);
|
||||
}
|
||||
|
||||
private _createModelReference(resource: URI): Promise<IReference<IResolvedTextEditorModel>> {
|
||||
private async doCreateModelReference(resource: URI): Promise<IReference<IResolvedTextEditorModel>> {
|
||||
|
||||
// Untitled Schema: go through cached input
|
||||
if (resource.scheme === network.Schemas.untitled) {
|
||||
return this.untitledEditorService.loadOrCreate({ resource }).then(model => new ImmortalReference(model as IResolvedTextEditorModel));
|
||||
const model = await this.untitledEditorService.loadOrCreate({ resource });
|
||||
|
||||
return new ImmortalReference(model as IResolvedTextEditorModel);
|
||||
}
|
||||
|
||||
// InMemory Schema: go through model service cache
|
||||
@@ -154,14 +159,15 @@ export class TextModelResolverService implements ITextModelService {
|
||||
|
||||
const ref = this.resourceModelCollection.acquire(resource.toString());
|
||||
|
||||
return ref.object.then(
|
||||
model => ({ object: model, dispose: () => ref.dispose() }),
|
||||
err => {
|
||||
ref.dispose();
|
||||
try {
|
||||
const model = await ref.object;
|
||||
|
||||
return Promise.reject(err);
|
||||
}
|
||||
);
|
||||
return { object: model as IResolvedTextEditorModel, dispose: () => ref.dispose() };
|
||||
} catch (error) {
|
||||
ref.dispose();
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
registerTextModelContentProvider(scheme: string, provider: ITextModelContentProvider): IDisposable {
|
||||
|
||||
@@ -71,6 +71,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
|
||||
if (reason !== ShutdownReason.LOAD && reason !== ShutdownReason.CLOSE) {
|
||||
return undefined; // only interested when window is closing or loading
|
||||
}
|
||||
|
||||
const workspaceIdentifier = this.getCurrentWorkspaceIdentifier();
|
||||
if (!workspaceIdentifier || !isEqualOrParent(workspaceIdentifier.configPath, this.environmentService.untitledWorkspacesHome)) {
|
||||
return undefined; // only care about untitled workspaces to ask for saving
|
||||
@@ -190,16 +191,23 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
|
||||
}
|
||||
}
|
||||
|
||||
private doUpdateFolders(foldersToAdd: IWorkspaceFolderCreationData[], foldersToDelete: URI[], index?: number, donotNotifyError: boolean = false): Promise<void> {
|
||||
return this.contextService.updateFolders(foldersToAdd, foldersToDelete, index)
|
||||
.then(() => null, error => donotNotifyError ? Promise.reject(error) : this.handleWorkspaceConfigurationEditingError(error));
|
||||
private async doUpdateFolders(foldersToAdd: IWorkspaceFolderCreationData[], foldersToDelete: URI[], index?: number, donotNotifyError: boolean = false): Promise<void> {
|
||||
try {
|
||||
await this.contextService.updateFolders(foldersToAdd, foldersToDelete, index);
|
||||
} catch (error) {
|
||||
if (donotNotifyError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.handleWorkspaceConfigurationEditingError(error);
|
||||
}
|
||||
}
|
||||
|
||||
addFolders(foldersToAdd: IWorkspaceFolderCreationData[], donotNotifyError: boolean = false): Promise<void> {
|
||||
return this.doAddFolders(foldersToAdd, undefined, donotNotifyError);
|
||||
}
|
||||
|
||||
private doAddFolders(foldersToAdd: IWorkspaceFolderCreationData[], index?: number, donotNotifyError: boolean = false): Promise<void> {
|
||||
private async doAddFolders(foldersToAdd: IWorkspaceFolderCreationData[], index?: number, donotNotifyError: boolean = false): Promise<void> {
|
||||
const state = this.contextService.getWorkbenchState();
|
||||
|
||||
// If we are in no-workspace or single-folder workspace, adding folders has to
|
||||
@@ -217,11 +225,18 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
|
||||
}
|
||||
|
||||
// Delegate addition of folders to workspace service otherwise
|
||||
return this.contextService.addFolders(foldersToAdd, index)
|
||||
.then(() => null, error => donotNotifyError ? Promise.reject(error) : this.handleWorkspaceConfigurationEditingError(error));
|
||||
try {
|
||||
await this.contextService.addFolders(foldersToAdd, index);
|
||||
} catch (error) {
|
||||
if (donotNotifyError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.handleWorkspaceConfigurationEditingError(error);
|
||||
}
|
||||
}
|
||||
|
||||
removeFolders(foldersToRemove: URI[], donotNotifyError: boolean = false): Promise<void> {
|
||||
async removeFolders(foldersToRemove: URI[], donotNotifyError: boolean = false): Promise<void> {
|
||||
|
||||
// If we are in single-folder state and the opened folder is to be removed,
|
||||
// we create an empty workspace and enter it.
|
||||
@@ -230,8 +245,15 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
|
||||
}
|
||||
|
||||
// Delegate removal of folders to workspace service otherwise
|
||||
return this.contextService.removeFolders(foldersToRemove)
|
||||
.then(() => null, error => donotNotifyError ? Promise.reject(error) : this.handleWorkspaceConfigurationEditingError(error));
|
||||
try {
|
||||
await this.contextService.removeFolders(foldersToRemove);
|
||||
} catch (error) {
|
||||
if (donotNotifyError) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
this.handleWorkspaceConfigurationEditingError(error);
|
||||
}
|
||||
}
|
||||
|
||||
private includesSingleFolderWorkspace(folders: URI[]): boolean {
|
||||
@@ -283,10 +305,12 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
|
||||
detail: nls.localize('workspaceOpenedDetail', "The workspace is already opened in another window. Please close that window first and then try again."),
|
||||
noLink: true
|
||||
};
|
||||
return this.windowService.showMessageBox(options).then(() => false);
|
||||
await this.windowService.showMessageBox(options);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return Promise.resolve(true); // OK
|
||||
return true; // OK
|
||||
}
|
||||
|
||||
private async saveWorkspaceAs(workspace: IWorkspaceIdentifier, targetConfigPathURI: URI): Promise<any> {
|
||||
|
||||
Reference in New Issue
Block a user