Skip to content

Commit 0dd3429

Browse files
authored
Revert "revert the feature (microsoft#187816)" (microsoft#187871)
This reverts commit 7895f9b.
1 parent eaabddd commit 0dd3429

File tree

6 files changed

+218
-8
lines changed

6 files changed

+218
-8
lines changed

src/vs/workbench/contrib/preferences/browser/preferencesRenderers.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/c
4444
import { isEqual } from 'vs/base/common/resources';
4545
import { IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
4646
import { IStringDictionary } from 'vs/base/common/collections';
47-
import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
47+
import { APPLY_ALL_PROFILES_SETTING, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
4848

4949
export interface IPreferencesRenderer extends IDisposable {
5050
render(): void;
@@ -616,6 +616,14 @@ class UnsupportedSettingsRenderer extends Disposable implements languages.CodeAc
616616
if (configuration.scope === ConfigurationScope.APPLICATION) {
617617
// If we're in a profile setting file, and the setting is application-scoped, fade it out.
618618
markerData.push(this.generateUnsupportedApplicationSettingMarker(setting));
619+
} else if (this.configurationService.isSettingAppliedForAllProfiles(setting.key)) {
620+
// If we're in the non-default profile setting file, and the setting can be applied in all profiles, fade it out.
621+
markerData.push({
622+
severity: MarkerSeverity.Hint,
623+
tags: [MarkerTag.Unnecessary],
624+
...setting.range,
625+
message: nls.localize('allProfileSettingWhileInNonDefaultProfileSetting', "This setting cannot be applied because it is configured to be applied in all profiles using setting {0}. Value from the default profile will be used instead.", APPLY_ALL_PROFILES_SETTING)
626+
});
619627
}
620628
}
621629
}

src/vs/workbench/contrib/preferences/browser/settingsTree.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { IObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree';
2323
import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
2424
import { ITreeFilter, ITreeModel, ITreeNode, ITreeRenderer, TreeFilterResult, TreeVisibility } from 'vs/base/browser/ui/tree/tree';
2525
import { Action, IAction, Separator } from 'vs/base/common/actions';
26+
import { distinct } from 'vs/base/common/arrays';
2627
import { Codicon } from 'vs/base/common/codicons';
2728
import { onUnexpectedError } from 'vs/base/common/errors';
2829
import { Emitter, Event } from 'vs/base/common/event';
@@ -63,7 +64,7 @@ import { ISettingsEditorViewState, SettingsTreeElement, SettingsTreeGroupChild,
6364
import { ExcludeSettingWidget, IListDataItem, IObjectDataItem, IObjectEnumOption, IObjectKeySuggester, IObjectValueSuggester, ISettingListChangeEvent, IncludeSettingWidget, ListSettingWidget, ObjectSettingCheckboxWidget, ObjectSettingDropdownWidget, ObjectValue } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
6465
import { LANGUAGE_SETTING_TAG, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences';
6566
import { settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/contrib/preferences/common/settingsEditorColorRegistry';
66-
import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
67+
import { APPLY_ALL_PROFILES_SETTING, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration';
6768
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
6869
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
6970
import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
@@ -901,6 +902,11 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
901902
}
902903

903904
template.indicatorsLabel.updateScopeOverrides(element, this._onDidClickOverrideElement, this._onApplyFilter);
905+
template.elementDisposables.add(this._configService.onDidChangeConfiguration(e => {
906+
if (e.affectsConfiguration(APPLY_ALL_PROFILES_SETTING)) {
907+
template.indicatorsLabel.updateScopeOverrides(element, this._onDidClickOverrideElement, this._onApplyFilter);
908+
}
909+
}));
904910

905911
const onChange = (value: any) => this._onDidChangeSetting.fire({
906912
key: element.setting.key,
@@ -1959,6 +1965,7 @@ export class SettingTreeRenderers {
19591965
@IInstantiationService private readonly _instantiationService: IInstantiationService,
19601966
@IContextMenuService private readonly _contextMenuService: IContextMenuService,
19611967
@IContextViewService private readonly _contextViewService: IContextViewService,
1968+
@IUserDataProfilesService private readonly _userDataProfilesService: IUserDataProfilesService,
19621969
@IUserDataSyncEnablementService private readonly _userDataSyncEnablementService: IUserDataSyncEnablementService,
19631970
) {
19641971
this.settingActions = [
@@ -2017,6 +2024,9 @@ export class SettingTreeRenderers {
20172024

20182025
private getActionsForSetting(setting: ISetting, settingTarget: SettingsTarget): IAction[] {
20192026
const actions: IAction[] = [];
2027+
if (this._userDataProfilesService.isEnabled() && setting.scope !== ConfigurationScope.APPLICATION && settingTarget === ConfigurationTarget.USER_LOCAL) {
2028+
actions.push(this._instantiationService.createInstance(ApplySettingToAllProfilesAction, setting));
2029+
}
20202030
if (this._userDataSyncEnablementService.isEnabled() && !setting.disallowSyncIgnore) {
20212031
actions.push(this._instantiationService.createInstance(SyncSettingAction, setting));
20222032
}
@@ -2486,3 +2496,40 @@ class SyncSettingAction extends Action {
24862496
}
24872497

24882498
}
2499+
2500+
class ApplySettingToAllProfilesAction extends Action {
2501+
static readonly ID = 'settings.applyToAllProfiles';
2502+
static readonly LABEL = localize('applyToAllProfiles', "Apply Setting to all Profiles");
2503+
2504+
constructor(
2505+
private readonly setting: ISetting,
2506+
@IWorkbenchConfigurationService private readonly configService: IWorkbenchConfigurationService,
2507+
) {
2508+
super(ApplySettingToAllProfilesAction.ID, ApplySettingToAllProfilesAction.LABEL);
2509+
this._register(Event.filter(configService.onDidChangeConfiguration, e => e.affectsConfiguration(APPLY_ALL_PROFILES_SETTING))(() => this.update()));
2510+
this.update();
2511+
}
2512+
2513+
update() {
2514+
const allProfilesSettings = this.configService.getValue<string[]>(APPLY_ALL_PROFILES_SETTING);
2515+
this.checked = allProfilesSettings.includes(this.setting.key);
2516+
}
2517+
2518+
override async run(): Promise<void> {
2519+
// first remove the current setting completely from ignored settings
2520+
const value = this.configService.getValue<string[]>(APPLY_ALL_PROFILES_SETTING) ?? [];
2521+
2522+
if (this.checked) {
2523+
value.splice(value.indexOf(this.setting.key), 1);
2524+
} else {
2525+
value.push(this.setting.key);
2526+
}
2527+
2528+
const newValue = distinct(value);
2529+
await this.configService.updateValue(APPLY_ALL_PROFILES_SETTING, newValue.length ? newValue : undefined, ConfigurationTarget.USER_LOCAL);
2530+
if (!this.checked) {
2531+
await this.configService.updateValue(this.setting.key, this.configService.inspect(this.setting.key).userLocal?.value, ConfigurationTarget.USER_LOCAL);
2532+
}
2533+
}
2534+
2535+
}

src/vs/workbench/services/configuration/browser/configuration.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { RunOnceScheduler } from 'vs/base/common/async';
1111
import { FileChangeType, FileChangesEvent, IFileService, whenProviderRegistered, FileOperationError, FileOperationResult, FileOperation, FileOperationEvent } from 'vs/platform/files/common/files';
1212
import { ConfigurationModel, ConfigurationModelParser, ConfigurationParseOptions, UserSettings } from 'vs/platform/configuration/common/configurationModels';
1313
import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels';
14-
import { TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration';
14+
import { TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, APPLY_ALL_PROFILES_SETTING } from 'vs/workbench/services/configuration/common/configuration';
1515
import { IStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
1616
import { WorkbenchState, IWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspace/common/workspace';
1717
import { ConfigurationScope, Extensions, IConfigurationRegistry, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
@@ -140,6 +140,14 @@ export class ApplicationConfiguration extends UserSettings {
140140
return this.loadConfiguration();
141141
}
142142

143+
override async loadConfiguration(): Promise<ConfigurationModel> {
144+
const model = await super.loadConfiguration();
145+
const value = model.getValue<string[]>(APPLY_ALL_PROFILES_SETTING);
146+
const allProfilesSettings = Array.isArray(value) ? value : [];
147+
return this.parseOptions.include || allProfilesSettings.length
148+
? this.reparse({ ...this.parseOptions, include: allProfilesSettings })
149+
: model;
150+
}
143151
}
144152

145153
export class UserConfiguration extends Disposable {

src/vs/workbench/services/configuration/browser/configurationService.ts

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { ConfigurationModel, ConfigurationChangeEvent, mergeChanges } from 'vs/p
1515
import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, isConfigurationOverrides, IConfigurationData, IConfigurationValue, IConfigurationChange, ConfigurationTargetToString, IConfigurationUpdateOverrides, isConfigurationUpdateOverrides, IConfigurationService, IConfigurationUpdateOptions } from 'vs/platform/configuration/common/configuration';
1616
import { IPolicyConfiguration, NullPolicyConfiguration, PolicyConfiguration } from 'vs/platform/configuration/common/configurations';
1717
import { Configuration } from 'vs/workbench/services/configuration/common/configurationModels';
18-
import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService, RestrictedSettings, PROFILE_SCOPES, LOCAL_MACHINE_PROFILE_SCOPES, profileSettingsSchemaId } from 'vs/workbench/services/configuration/common/configuration';
18+
import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService, RestrictedSettings, PROFILE_SCOPES, LOCAL_MACHINE_PROFILE_SCOPES, profileSettingsSchemaId, APPLY_ALL_PROFILES_SETTING } from 'vs/workbench/services/configuration/common/configuration';
1919
import { Registry } from 'vs/platform/registry/common/platform';
2020
import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings, machineOverridableSettings, ConfigurationScope, IConfigurationPropertySchema, keyFromOverrideIdentifiers, OVERRIDE_PROPERTY_PATTERN, resourceLanguageSettingsSchemaId, configurationDefaultsSchemaId } from 'vs/platform/configuration/common/configurationRegistry';
2121
import { IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, getStoredWorkspaceFolder, toWorkspaceFolders } from 'vs/platform/workspaces/common/workspaces';
@@ -44,6 +44,7 @@ import { IPolicyService, NullPolicyService } from 'vs/platform/policy/common/pol
4444
import { IUserDataProfile, IUserDataProfilesService } from 'vs/platform/userDataProfile/common/userDataProfile';
4545
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
4646
import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
47+
import { workbenchConfigurationNodeBase } from 'vs/workbench/common/configuration';
4748

4849
function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined {
4950
return userDataProfile.isDefault
@@ -489,7 +490,11 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat
489490
}
490491

491492
isSettingAppliedForAllProfiles(key: string): boolean {
492-
return this.configurationRegistry.getConfigurationProperties()[key]?.scope === ConfigurationScope.APPLICATION;
493+
if (this.configurationRegistry.getConfigurationProperties()[key]?.scope === ConfigurationScope.APPLICATION) {
494+
return true;
495+
}
496+
const allProfilesSettings = this.getValue<string[]>(APPLY_ALL_PROFILES_SETTING) ?? [];
497+
return Array.isArray(allProfilesSettings) && allProfilesSettings.includes(key);
493498
}
494499

495500
private async createWorkspace(arg: IAnyWorkspaceIdentifier): Promise<Workspace> {
@@ -601,6 +606,10 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat
601606
const initUserConfiguration = async () => {
602607
mark('code/willInitUserConfiguration');
603608
const result = await Promise.all([this.localUserConfiguration.initialize(), this.remoteUserConfiguration ? this.remoteUserConfiguration.initialize() : Promise.resolve(new ConfigurationModel())]);
609+
if (this.applicationConfiguration) {
610+
const applicationConfigurationModel = await initApplicationConfigurationPromise;
611+
result[0] = this.localUserConfiguration.reparse({ exclude: applicationConfigurationModel.getValue(APPLY_ALL_PROFILES_SETTING) });
612+
}
604613
mark('code/didInitUserConfiguration');
605614
return result;
606615
};
@@ -714,8 +723,12 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat
714723
promises.push(this.reloadApplicationConfiguration(true));
715724
}
716725
}
717-
const [localUser, application] = await Promise.all(promises);
718-
await this.loadConfiguration(application ?? this._configuration.applicationConfiguration, localUser, this._configuration.remoteUserConfiguration, true);
726+
let [localUser, application] = await Promise.all(promises);
727+
application = application ?? this._configuration.applicationConfiguration;
728+
if (this.applicationConfiguration) {
729+
localUser = this.localUserConfiguration.reparse({ exclude: application.getValue(APPLY_ALL_PROFILES_SETTING) });
730+
}
731+
await this.loadConfiguration(application, localUser, this._configuration.remoteUserConfiguration, true);
719732
})());
720733
}
721734

@@ -758,15 +771,35 @@ export class WorkspaceService extends Disposable implements IWorkbenchConfigurat
758771

759772
private onApplicationConfigurationChanged(applicationConfiguration: ConfigurationModel): void {
760773
const previous = { data: this._configuration.toData(), workspace: this.workspace };
774+
const previousAllProfilesSettings = this._configuration.applicationConfiguration.getValue<string[]>(APPLY_ALL_PROFILES_SETTING) ?? [];
761775
const change = this._configuration.compareAndUpdateApplicationConfiguration(applicationConfiguration);
776+
const currentAllProfilesSettings = this.getValue<string[]>(APPLY_ALL_PROFILES_SETTING) ?? [];
762777
const configurationProperties = this.configurationRegistry.getConfigurationProperties();
763778
const changedKeys: string[] = [];
764779
for (const changedKey of change.keys) {
765780
if (configurationProperties[changedKey]?.scope === ConfigurationScope.APPLICATION) {
766781
changedKeys.push(changedKey);
782+
if (changedKey === APPLY_ALL_PROFILES_SETTING) {
783+
for (const previousAllProfileSetting of previousAllProfilesSettings) {
784+
if (!currentAllProfilesSettings.includes(previousAllProfileSetting)) {
785+
changedKeys.push(previousAllProfileSetting);
786+
}
787+
}
788+
for (const currentAllProfileSetting of currentAllProfilesSettings) {
789+
if (!previousAllProfilesSettings.includes(currentAllProfileSetting)) {
790+
changedKeys.push(currentAllProfileSetting);
791+
}
792+
}
793+
}
794+
}
795+
else if (currentAllProfilesSettings.includes(changedKey)) {
796+
changedKeys.push(changedKey);
767797
}
768798
}
769799
change.keys = changedKeys;
800+
if (change.keys.includes(APPLY_ALL_PROFILES_SETTING)) {
801+
this._configuration.updateLocalUserConfiguration(this.localUserConfiguration.reparse({ exclude: currentAllProfilesSettings }));
802+
}
770803
this.triggerConfigurationChange(change, previous, ConfigurationTarget.USER);
771804
}
772805

@@ -1318,3 +1351,18 @@ const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegist
13181351
workbenchContributionsRegistry.registerWorkbenchContribution(RegisterConfigurationSchemasContribution, LifecyclePhase.Restored);
13191352
workbenchContributionsRegistry.registerWorkbenchContribution(ResetConfigurationDefaultsOverridesCache, LifecyclePhase.Eventually);
13201353
workbenchContributionsRegistry.registerWorkbenchContribution(UpdateExperimentalSettingsDefaults, LifecyclePhase.Restored);
1354+
1355+
const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
1356+
configurationRegistry.registerConfiguration({
1357+
...workbenchConfigurationNodeBase,
1358+
properties: {
1359+
[APPLY_ALL_PROFILES_SETTING]: {
1360+
'type': 'array',
1361+
description: localize('setting description', "Configure settings to be applied for all profiles."),
1362+
'default': [],
1363+
'scope': ConfigurationScope.APPLICATION,
1364+
additionalProperties: true,
1365+
uniqueItems: true,
1366+
}
1367+
}
1368+
});

src/vs/workbench/services/configuration/common/configuration.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,5 @@ export interface IWorkbenchConfigurationService extends IConfigurationService {
9393
}
9494

9595
export const TASKS_DEFAULT = '{\n\t\"version\": \"2.0.0\",\n\t\"tasks\": []\n}';
96+
97+
export const APPLY_ALL_PROFILES_SETTING = 'workbench.settings.applyToAllProfiles';

0 commit comments

Comments
 (0)