diff --git a/src/vs/platform/configuration/common/configuration.ts b/src/vs/platform/configuration/common/configuration.ts index 7f14056f1d980..d5b333f73cef2 100644 --- a/src/vs/platform/configuration/common/configuration.ts +++ b/src/vs/platform/configuration/common/configuration.ts @@ -114,7 +114,7 @@ export interface IConfigurationService { inspect(key: string, overrides?: IConfigurationOverrides): IConfigurationValue; - reloadConfiguration(folder?: IWorkspaceFolder): Promise; + reloadConfiguration(target?: ConfigurationTarget | IWorkspaceFolder): Promise; keys(): { default: string[]; diff --git a/src/vs/platform/userDataSync/common/keybindingsSync.ts b/src/vs/platform/userDataSync/common/keybindingsSync.ts index 80f54b97a02e4..7f93636705bcf 100644 --- a/src/vs/platform/userDataSync/common/keybindingsSync.ts +++ b/src/vs/platform/userDataSync/common/keybindingsSync.ts @@ -23,6 +23,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { URI } from 'vs/base/common/uri'; import { IStorageService } from 'vs/platform/storage/common/storage'; import { VSBuffer } from 'vs/base/common/buffer'; +import { Event } from 'vs/base/common/event'; interface ISyncContent { mac?: string; @@ -35,6 +36,10 @@ interface IKeybindingsResourcePreview extends IFileResourcePreview { previewResult: IMergeResult; } +interface ILastSyncUserData extends IRemoteUserData { + platformSpecific?: boolean; +} + export function getKeybindingsContentFromSyncContent(syncContent: string, platformSpecific: boolean): string | null { const parsed = JSON.parse(syncContent); if (!platformSpecific) { @@ -72,11 +77,12 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem @ITelemetryService telemetryService: ITelemetryService, ) { super(environmentService.keybindingsResource, SyncResource.Keybindings, fileService, environmentService, storageService, userDataSyncStoreService, userDataSyncBackupStoreService, userDataSyncResourceEnablementService, telemetryService, logService, userDataSyncUtilService, configurationService); + this._register(Event.filter(configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('settingsSync.keybindingsPerPlatform'))(() => this.triggerLocalChange())); } - protected async generateSyncPreview(remoteUserData: IRemoteUserData, lastSyncUserData: IRemoteUserData | null, token: CancellationToken): Promise { + protected async generateSyncPreview(remoteUserData: IRemoteUserData, lastSyncUserData: ILastSyncUserData | null, token: CancellationToken): Promise { const remoteContent = remoteUserData.syncData ? this.getKeybindingsContentFromSyncContent(remoteUserData.syncData.content) : null; - const lastSyncContent: string | null = lastSyncUserData && lastSyncUserData.syncData ? this.getKeybindingsContentFromSyncContent(lastSyncUserData.syncData.content) : null; + const lastSyncContent: string | null = lastSyncUserData ? this.getKeybindingsContentFromLastSyncUserData(lastSyncUserData) : null; // Get file content last to get the latest const fileContent = await this.getLocalFileContent(); @@ -204,7 +210,7 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem if (localChange !== Change.None) { this.logService.trace(`${this.syncResourceLogLabel}: Updating local keybindings...`); if (fileContent) { - await this.backupLocal(this.toSyncContent(fileContent.value.toString(), null)); + await this.backupLocal(this.toSyncContent(fileContent.value.toString())); } await this.updateLocalFileContent(content || '[]', fileContent, force); this.logService.info(`${this.syncResourceLogLabel}: Updated local keybindings`); @@ -212,7 +218,7 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem if (remoteChange !== Change.None) { this.logService.trace(`${this.syncResourceLogLabel}: Updating remote keybindings...`); - const remoteContents = this.toSyncContent(content || '[]', remoteUserData.syncData ? remoteUserData.syncData.content : null); + const remoteContents = this.toSyncContent(content || '[]', remoteUserData.syncData?.content); remoteUserData = await this.updateRemoteUserData(remoteContents, force ? null : remoteUserData.ref); this.logService.info(`${this.syncResourceLogLabel}: Updated remote keybindings`); } @@ -224,15 +230,7 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem if (lastSyncUserData?.ref !== remoteUserData.ref) { this.logService.trace(`${this.syncResourceLogLabel}: Updating last synchronized keybindings...`); - const lastSyncContent = content !== null ? this.toSyncContent(content, null) : remoteUserData.syncData?.content; - await this.updateLastSyncUserData({ - ref: remoteUserData.ref, - syncData: lastSyncContent ? { - version: remoteUserData.syncData ? remoteUserData.syncData.version : this.version, - machineId: remoteUserData.syncData!.machineId, - content: lastSyncContent - } : null - }); + await this.updateLastSyncUserData(remoteUserData, { platformSpecific: this.syncKeybindingsPerPlatform() }); this.logService.info(`${this.syncResourceLogLabel}: Updated last synchronized keybindings`); } @@ -281,6 +279,19 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem return null; } + private getKeybindingsContentFromLastSyncUserData(lastSyncUserData: ILastSyncUserData): string | null { + if (!lastSyncUserData.syncData) { + return null; + } + + // Return null if there is a change in platform specific property from last time sync. + if (lastSyncUserData.platformSpecific !== undefined && lastSyncUserData.platformSpecific !== this.syncKeybindingsPerPlatform()) { + return null; + } + + return this.getKeybindingsContentFromSyncContent(lastSyncUserData.syncData.content); + } + private getKeybindingsContentFromSyncContent(syncContent: string): string | null { try { return getKeybindingsContentFromSyncContent(syncContent, this.syncKeybindingsPerPlatform()); @@ -290,7 +301,7 @@ export class KeybindingsSynchroniser extends AbstractJsonFileSynchroniser implem } } - private toSyncContent(keybindingsContent: string, syncContent: string | null): string { + private toSyncContent(keybindingsContent: string, syncContent?: string): string { let parsed: ISyncContent = {}; try { parsed = JSON.parse(syncContent || '{}'); diff --git a/src/vs/platform/userDataSync/common/settingsSync.ts b/src/vs/platform/userDataSync/common/settingsSync.ts index 6b583f9c809f8..d4e31ee05b7c3 100644 --- a/src/vs/platform/userDataSync/common/settingsSync.ts +++ b/src/vs/platform/userDataSync/common/settingsSync.ts @@ -13,7 +13,7 @@ import { VSBuffer } from 'vs/base/common/buffer'; import { localize } from 'vs/nls'; import { Event } from 'vs/base/common/event'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; -import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { CancellationToken } from 'vs/base/common/cancellation'; import { updateIgnoredSettings, merge, getIgnoredSettings, isEmpty } from 'vs/platform/userDataSync/common/settingsMerge'; import { edit } from 'vs/platform/userDataSync/common/content'; @@ -198,6 +198,7 @@ export class SettingsSynchroniser extends AbstractJsonFileSynchroniser implement await this.backupLocal(JSON.stringify(this.toSettingsSyncContent(fileContent.value.toString()))); } await this.updateLocalFileContent(content, fileContent, force); + await this.configurationService.reloadConfiguration(ConfigurationTarget.USER_LOCAL); this.logService.info(`${this.syncResourceLogLabel}: Updated local settings`); } diff --git a/src/vs/workbench/services/configuration/browser/configurationService.ts b/src/vs/workbench/services/configuration/browser/configurationService.ts index 2e23db80ae732..f0fc6c907e68f 100644 --- a/src/vs/workbench/services/configuration/browser/configurationService.ts +++ b/src/vs/workbench/services/configuration/browser/configurationService.ts @@ -285,13 +285,38 @@ export class WorkspaceService extends Disposable implements IConfigurationServic }); } - reloadConfiguration(folder?: IWorkspaceFolder, key?: string): Promise { - if (folder) { - return this.reloadWorkspaceFolderConfiguration(folder, key); + async reloadConfiguration(target?: ConfigurationTarget | IWorkspaceFolder): Promise { + if (target === undefined) { + const { local, remote } = await this.reloadUserConfiguration(); + await this.reloadWorkspaceConfiguration(); + await this.loadConfiguration(local, remote); + return; + } + + if (IWorkspaceFolder.isIWorkspaceFolder(target)) { + await this.reloadWorkspaceFolderConfiguration(target); + return; + } + + switch (target) { + case ConfigurationTarget.USER: + const { local, remote } = await this.reloadUserConfiguration(); + await this.loadConfiguration(local, remote); + return; + + case ConfigurationTarget.USER_LOCAL: + await this.reloadLocalUserConfiguration(); + return; + + case ConfigurationTarget.USER_REMOTE: + await this.reloadRemoteUserConfiguration(); + return; + + case ConfigurationTarget.WORKSPACE: + case ConfigurationTarget.WORKSPACE_FOLDER: + await this.reloadWorkspaceConfiguration(); + return; } - return this.reloadUserConfiguration() - .then(({ local, remote }) => this.reloadWorkspaceConfiguration() - .then(() => this.loadConfiguration(local, remote))); } inspect(key: string, overrides?: IConfigurationOverrides): IConfigurationValue { @@ -465,10 +490,10 @@ export class WorkspaceService extends Disposable implements IConfigurationServic return new ConfigurationModel(); } - private reloadWorkspaceConfiguration(key?: string): Promise { + private reloadWorkspaceConfiguration(): Promise { const workbenchState = this.getWorkbenchState(); if (workbenchState === WorkbenchState.FOLDER) { - return this.onWorkspaceFolderConfigurationChanged(this.workspace.folders[0], key); + return this.onWorkspaceFolderConfigurationChanged(this.workspace.folders[0]); } if (workbenchState === WorkbenchState.WORKSPACE) { return this.workspaceConfiguration.reload().then(() => this.onWorkspaceConfigurationChanged()); @@ -476,8 +501,8 @@ export class WorkspaceService extends Disposable implements IConfigurationServic return Promise.resolve(undefined); } - private reloadWorkspaceFolderConfiguration(folder: IWorkspaceFolder, key?: string): Promise { - return this.onWorkspaceFolderConfigurationChanged(folder, key); + private reloadWorkspaceFolderConfiguration(folder: IWorkspaceFolder): Promise { + return this.onWorkspaceFolderConfigurationChanged(folder); } private loadConfiguration(userConfigurationModel: ConfigurationModel, remoteUserConfigurationModel: ConfigurationModel): Promise { @@ -592,7 +617,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic } } - private onWorkspaceFolderConfigurationChanged(folder: IWorkspaceFolder, key?: string): Promise { + private onWorkspaceFolderConfigurationChanged(folder: IWorkspaceFolder): Promise { return this.loadFolderConfigurations([folder]) .then(([folderConfiguration]) => { const previous = { data: this._configuration.toData(), workspace: this.workspace }; @@ -700,7 +725,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic case EditableConfigurationTarget.WORKSPACE_FOLDER: const workspaceFolder = overrides && overrides.resource ? this.workspace.getFolder(overrides.resource) : null; if (workspaceFolder) { - return this.reloadWorkspaceFolderConfiguration(workspaceFolder, key); + return this.reloadWorkspaceFolderConfiguration(workspaceFolder); } } return Promise.resolve();