Skip to content

Commit 040ac30

Browse files
authored
microsoft#255797 prepare for auto refetching (microsoft#257055)
1 parent b37c013 commit 040ac30

File tree

10 files changed

+125
-34
lines changed

10 files changed

+125
-34
lines changed

src/vs/editor/common/config/editorConfigurationSchema.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,31 +115,46 @@ const editorConfiguration: IConfigurationNode = {
115115
type: 'boolean',
116116
default: false,
117117
markdownDescription: nls.localize('editor.experimental.treeSitterTelemetry', "Controls whether tree sitter parsing should be turned on and telemetry collected. Setting `editor.experimental.preferTreeSitter` for specific languages will take precedence."),
118-
tags: ['experimental', 'onExP']
118+
tags: ['experimental'],
119+
experiment: {
120+
autoRefetch: false
121+
}
119122
},
120123
'editor.experimental.preferTreeSitter.css': {
121124
type: 'boolean',
122125
default: false,
123126
markdownDescription: nls.localize('editor.experimental.preferTreeSitter.css', "Controls whether tree sitter parsing should be turned on for css. This will take precedence over `editor.experimental.treeSitterTelemetry` for css."),
124-
tags: ['experimental', 'onExP']
127+
tags: ['experimental'],
128+
experiment: {
129+
autoRefetch: false
130+
}
125131
},
126132
'editor.experimental.preferTreeSitter.typescript': {
127133
type: 'boolean',
128134
default: false,
129135
markdownDescription: nls.localize('editor.experimental.preferTreeSitter.typescript', "Controls whether tree sitter parsing should be turned on for typescript. This will take precedence over `editor.experimental.treeSitterTelemetry` for typescript."),
130-
tags: ['experimental', 'onExP']
136+
tags: ['experimental'],
137+
experiment: {
138+
autoRefetch: false
139+
}
131140
},
132141
'editor.experimental.preferTreeSitter.ini': {
133142
type: 'boolean',
134143
default: false,
135144
markdownDescription: nls.localize('editor.experimental.preferTreeSitter.ini', "Controls whether tree sitter parsing should be turned on for ini. This will take precedence over `editor.experimental.treeSitterTelemetry` for ini."),
136-
tags: ['experimental', 'onExP']
145+
tags: ['experimental'],
146+
experiment: {
147+
autoRefetch: false
148+
}
137149
},
138150
'editor.experimental.preferTreeSitter.regex': {
139151
type: 'boolean',
140152
default: false,
141153
markdownDescription: nls.localize('editor.experimental.preferTreeSitter.regex', "Controls whether tree sitter parsing should be turned on for regex. This will take precedence over `editor.experimental.treeSitterTelemetry` for regex."),
142-
tags: ['experimental', 'onExP']
154+
tags: ['experimental'],
155+
experiment: {
156+
autoRefetch: false
157+
}
143158
},
144159
'editor.language.brackets': {
145160
type: ['array', 'null'],

src/vs/editor/common/config/editorOptions.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4468,14 +4468,20 @@ class InlineEditorSuggest extends BaseEditorOption<EditorOption.inlineSuggest, I
44684468
'editor.inlineSuggest.experimental.suppressInlineSuggestions': {
44694469
type: 'string',
44704470
default: defaults.experimental.suppressInlineSuggestions,
4471-
tags: ['experimental', 'onExp'],
4472-
description: nls.localize('inlineSuggest.suppressInlineSuggestions', "Suppresses inline completions for specified extension IDs -- comma separated.")
4471+
tags: ['experimental'],
4472+
description: nls.localize('inlineSuggest.suppressInlineSuggestions', "Suppresses inline completions for specified extension IDs -- comma separated."),
4473+
experiment: {
4474+
autoRefetch: false
4475+
}
44734476
},
44744477
'editor.inlineSuggest.experimental.triggerCommandOnProviderChange': {
44754478
type: 'boolean',
44764479
default: defaults.experimental.triggerCommandOnProviderChange,
4477-
tags: ['experimental', 'onExp'],
4478-
description: nls.localize('inlineSuggest.triggerCommandOnProviderChange', "Controls whether to trigger a command when the inline suggestion provider changes.")
4480+
tags: ['experimental'],
4481+
description: nls.localize('inlineSuggest.triggerCommandOnProviderChange', "Controls whether to trigger a command when the inline suggestion provider changes."),
4482+
experiment: {
4483+
autoRefetch: false
4484+
}
44794485
},
44804486
'editor.inlineSuggest.fontFamily': {
44814487
type: 'string',
@@ -6328,7 +6334,9 @@ export const EditorOptions = {
63286334
10, 0, Constants.MAX_SAFE_SMALL_INTEGER,
63296335
{
63306336
description: nls.localize('quickSuggestionsDelay', "Controls the delay in milliseconds after which quick suggestions will show up."),
6331-
tags: ['onExP']
6337+
experiment: {
6338+
autoRefetch: false
6339+
}
63326340
}
63336341
)),
63346342
readOnly: register(new EditorBooleanOption(

src/vs/platform/configuration/common/configurationRegistry.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ export interface IConfigurationPropertySchema extends IJSONSchema {
176176
* List of tags associated to the property.
177177
* - A tag can be used for filtering
178178
* - Use `experimental` tag for marking the setting as experimental.
179-
* - Use `onExP` tag for marking that the default of the setting can be changed by running experiments.
180179
*/
181180
tags?: string[];
182181

@@ -217,6 +216,23 @@ export interface IConfigurationPropertySchema extends IJSONSchema {
217216
* a system-wide policy.
218217
*/
219218
policy?: IPolicy;
219+
220+
/**
221+
* When specified, this setting's default value can always be overwritten by
222+
* an experiment.
223+
*/
224+
experiment?: {
225+
/**
226+
* Whether to automatically refetch the experiment data and
227+
* update the configuration.
228+
*/
229+
autoRefetch: boolean;
230+
231+
/**
232+
* The name of the experiment. By default, this is `config.${settingId}`
233+
*/
234+
name?: string;
235+
};
220236
}
221237

222238
export interface IExtensionInfo {
@@ -657,6 +673,11 @@ class ConfigurationRegistry extends Disposable implements IConfigurationRegistry
657673
property.restricted = types.isUndefinedOrNull(property.restricted) ? !!restrictedProperties?.includes(key) : property.restricted;
658674
}
659675

676+
if (property.experiment) {
677+
property.tags = property.tags ?? [];
678+
property.tags.push('onExP');
679+
}
680+
660681
const excluded = properties[key].hasOwnProperty('included') && !properties[key].included;
661682
const policyName = properties[key].policy?.name;
662683

@@ -679,6 +700,7 @@ class ConfigurationRegistry extends Disposable implements IConfigurationRegistry
679700
}
680701
}
681702

703+
682704
}
683705
}
684706
const subNodes = configuration.allOf;

src/vs/workbench/api/common/configurationExtensionPoint.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,11 @@ configurationExtPoint.setHandler((extensions, { added, removed }) => {
271271
if (extensionConfigurationPolicy?.[key]) {
272272
propertyConfiguration.policy = extensionConfigurationPolicy?.[key];
273273
}
274+
if (propertyConfiguration.tags?.some(tag => tag.toLowerCase() === 'onexp')) {
275+
propertyConfiguration.experiment = {
276+
autoRefetch: false
277+
};
278+
}
274279
seenProperties.add(key);
275280
propertyConfiguration.scope = propertyConfiguration.scope ? parseScope(propertyConfiguration.scope.toString()) : ConfigurationScope.WINDOW;
276281
}

src/vs/workbench/browser/workbench.contribution.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,9 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
538538
'type': 'string',
539539
'enum': ['hidden', 'visibleInWorkspace', 'visible', 'maximizedInWorkspace', 'maximized'],
540540
'default': 'hidden',
541-
'tags': ['onExp'],
541+
'experiment': {
542+
autoRefetch: false
543+
},
542544
'description': localize('secondarySideBarDefaultVisibility', "Controls the default visibility of the secondary side bar in workspaces or empty windows opened for the first time."),
543545
'enumDescriptions': [
544546
localize('workbench.secondarySideBar.defaultVisibility.hidden', "The secondary side bar is hidden by default."),
@@ -626,7 +628,10 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
626628
'type': 'boolean',
627629
'default': product.quality !== 'stable',
628630
'description': localize('settings.showAISearchToggle', "Controls whether the AI search results toggle is shown in the search bar in the Settings editor after doing a search and once AI search results are available."),
629-
'tags': ['experimental', 'onExP']
631+
'tags': ['experimental'],
632+
'experiment': {
633+
autoRefetch: false
634+
}
630635
},
631636
'workbench.hover.delay': {
632637
'type': 'number',

src/vs/workbench/contrib/chat/browser/chat.contribution.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,13 +260,19 @@ configurationRegistry.registerConfiguration({
260260
type: 'string',
261261
enum: ['inline', 'hover', 'input', 'none'],
262262
default: 'inline',
263-
tags: ['experimental', 'onExp'],
263+
tags: ['experimental'],
264+
experiment: {
265+
autoRefetch: false
266+
}
264267
},
265268
'chat.emptyChatState.enabled': {
266269
type: 'boolean',
267270
default: true,
268271
description: nls.localize('chat.emptyChatState', "Shows a modified empty chat state with hints in the input placeholder text."),
269-
tags: ['experimental', 'onExp'],
272+
tags: ['experimental'],
273+
experiment: {
274+
autoRefetch: false
275+
}
270276
},
271277
'chat.checkpoints.enabled': {
272278
type: 'boolean',
@@ -321,7 +327,9 @@ configurationRegistry.registerConfiguration({
321327
type: 'boolean',
322328
description: nls.localize('chat.edits2Enabled', "Enable the new Edits mode that is based on tool-calling. When this is enabled, models that don't support tool-calling are unavailable for Edits mode."),
323329
default: true,
324-
tags: ['onExp'],
330+
experiment: {
331+
autoRefetch: false
332+
}
325333
},
326334
[ChatConfiguration.ExtensionToolsEnabled]: {
327335
type: 'boolean',
@@ -337,7 +345,9 @@ configurationRegistry.registerConfiguration({
337345
type: 'boolean',
338346
description: nls.localize('chat.agent.enabled.description', "Enable agent mode for {0}. When this is enabled, agent mode can be activated via the dropdown in the view.", 'Copilot Chat'),
339347
default: true,
340-
tags: ['onExp'],
348+
experiment: {
349+
autoRefetch: false
350+
},
341351
policy: {
342352
name: 'ChatAgentMode',
343353
minimumVersion: '1.99',
@@ -499,7 +509,10 @@ configurationRegistry.registerConfiguration({
499509
enum: ['default', 'apple'],
500510
description: nls.localize('chat.signInDialogVariant', "Control variations of the sign-in dialog."),
501511
default: 'default',
502-
tags: ['onExp', 'experimental']
512+
tags: ['experimental'],
513+
experiment: {
514+
autoRefetch: false
515+
}
503516
}
504517
}
505518
});

src/vs/workbench/contrib/editTelemetry/browser/editTelemetry.contribution.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ configurationRegistry.registerConfiguration({
3535
markdownDescription: localize('telemetry.editStats.detailed.enabled', "Controls whether to enable telemetry for detailed edit statistics (only sends statistics if general telemetry is enabled)."),
3636
type: 'boolean',
3737
default: false,
38-
tags: ['experimental', 'onExP'],
38+
tags: ['experimental'],
39+
experiment: {
40+
autoRefetch: false
41+
}
3942
},
4043
[EDIT_TELEMETRY_SHOW_STATUS_BAR]: {
4144
markdownDescription: localize('telemetry.editStats.showStatusBar', "Controls whether to show the status bar for edit telemetry."),

src/vs/workbench/contrib/inlineChat/common/inlineChat.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,19 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat
6363
description: localize('enableV2', "Whether to use the next version of inline chat."),
6464
default: false,
6565
type: 'boolean',
66-
tags: ['preview', 'onExp'],
66+
tags: ['preview'],
67+
experiment: {
68+
autoRefetch: false
69+
}
6770
},
6871
[InlineChatConfigKeys.HideOnRequest]: {
6972
markdownDescription: localize('hideOnRequest', "Whether to hide the inline chat widget after making a request. When enabled, the widget hides after a request has been made and instead the chat overlay shows. When hidden, the widget can always be shown again with the inline chat keybinding or from the chat overlay widget. *Note* that this setting requires `#inlineChat.enableV2#` to be enabled."),
7073
default: false,
7174
type: 'boolean',
72-
tags: ['preview', 'onExp'],
75+
tags: ['preview'],
76+
experiment: {
77+
autoRefetch: false
78+
}
7379
},
7480
}
7581
});

src/vs/workbench/contrib/performance/electron-browser/performance.contribution.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,11 @@ Registry.as<IConfigurationRegistry>(ConfigExt.Configuration).registerConfigurati
4040
'application.experimental.rendererProfiling': {
4141
type: 'boolean',
4242
default: false,
43-
tags: ['experimental', 'onExP'],
44-
markdownDescription: localize('experimental.rendererProfiling', "When enabled, slow renderers are automatically profiled.")
43+
tags: ['experimental'],
44+
markdownDescription: localize('experimental.rendererProfiling', "When enabled, slow renderers are automatically profiled."),
45+
experiment: {
46+
autoRefetch: false
47+
}
4548
}
4649
}
4750
});

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

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Event, Emitter } from '../../../../base/common/event.js';
88
import { ResourceMap } from '../../../../base/common/map.js';
99
import { equals } from '../../../../base/common/objects.js';
1010
import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
11-
import { Queue, Barrier, Promises, Delayer } from '../../../../base/common/async.js';
11+
import { Queue, Barrier, Promises, Delayer, RunOnceScheduler } from '../../../../base/common/async.js';
1212
import { IJSONContributionRegistry, Extensions as JSONExtensions } from '../../../../platform/jsonschemas/common/jsonContributionRegistry.js';
1313
import { IWorkspaceContextService, Workspace as BaseWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, WorkspaceFolder, toWorkspaceFolder, isWorkspaceFolder, IWorkspaceFoldersWillChangeEvent, IEmptyWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier, IAnyWorkspaceIdentifier } from '../../../../platform/workspace/common/workspace.js';
1414
import { ConfigurationModel, ConfigurationChangeEvent, mergeChanges } from '../../../../platform/configuration/common/configurationModels.js';
@@ -47,6 +47,7 @@ import { IBrowserWorkbenchEnvironmentService } from '../../environment/browser/e
4747
import { workbenchConfigurationNodeBase } from '../../../common/configuration.js';
4848
import { mainWindow } from '../../../../base/browser/window.js';
4949
import { runWhenWindowIdle } from '../../../../base/browser/dom.js';
50+
import { ASSIGNMENT_REFETCH_INTERVAL } from '../../../../platform/assignment/common/assignment.js';
5051

5152
function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined {
5253
const isDefaultProfile = userDataProfile.isDefault || userDataProfile.useDefaultFlags?.settings;
@@ -1338,7 +1339,9 @@ class ConfigurationDefaultOverridesContribution extends Disposable implements IW
13381339
static readonly ID = 'workbench.contrib.configurationDefaultOverridesContribution';
13391340

13401341
private readonly processedExperimentalSettings = new Set<string>();
1342+
private readonly autoRefetchExperimentalSettings = new Set<string>();
13411343
private readonly configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
1344+
private readonly autoRefetchExperimentalSettingsScheduler: RunOnceScheduler;
13421345

13431346
constructor(
13441347
@IWorkbenchAssignmentService private readonly workbenchAssignmentService: IWorkbenchAssignmentService,
@@ -1348,17 +1351,23 @@ class ConfigurationDefaultOverridesContribution extends Disposable implements IW
13481351
) {
13491352
super();
13501353

1354+
this.autoRefetchExperimentalSettingsScheduler = new RunOnceScheduler(() => {
1355+
this.processExperimentalSettings(this.autoRefetchExperimentalSettings, true);
1356+
this.autoRefetchExperimentalSettingsScheduler.schedule();
1357+
}, ASSIGNMENT_REFETCH_INTERVAL);
1358+
13511359
this.updateDefaults();
13521360

13531361
// When configuration is updated make sure to apply experimental configuration overrides
1354-
this._register(this.configurationRegistry.onDidUpdateConfiguration(({ properties }) => this.processExperimentalSettings(properties)));
1362+
this._register(this.configurationRegistry.onDidUpdateConfiguration(({ properties }) => this.processExperimentalSettings(properties, false)));
1363+
13551364
}
13561365

13571366
private async updateDefaults(): Promise<void> {
13581367
this.logService.trace('ConfigurationService#updateDefaults: begin');
13591368
try {
13601369
// Check for experiments
1361-
await this.processExperimentalSettings(Object.keys(this.configurationRegistry.getConfigurationProperties()));
1370+
await this.processExperimentalSettings(Object.keys(this.configurationRegistry.getConfigurationProperties()), false);
13621371
} finally {
13631372
// Invalidate defaults cache after extensions have registered
13641373
// and after the experiments have been resolved to prevent
@@ -1367,26 +1376,28 @@ class ConfigurationDefaultOverridesContribution extends Disposable implements IW
13671376
this.logService.trace('ConfigurationService#updateDefaults: resetting the defaults');
13681377
this.configurationService.reloadConfiguration(ConfigurationTarget.DEFAULT);
13691378
}
1379+
1380+
// Schedule auto-refetch of experimental settings
1381+
this.autoRefetchExperimentalSettingsScheduler.schedule();
13701382
}
13711383

1372-
private async processExperimentalSettings(properties: Iterable<string>): Promise<void> {
1384+
private async processExperimentalSettings(properties: Iterable<string>, autoRefetch: boolean): Promise<void> {
13731385
const overrides: IStringDictionary<any> = {};
13741386
const allProperties = this.configurationRegistry.getConfigurationProperties();
13751387
for (const property of properties) {
13761388
const schema = allProperties[property];
1377-
const tags = schema?.tags;
1378-
// Many experimental settings refer to in-development or unstable settings.
1379-
// onExP more clearly indicates that the setting could be
1380-
// part of an experiment.
1381-
if (!tags || !tags.some(tag => tag.toLowerCase() === 'onexp')) {
1389+
if (!schema.experiment) {
13821390
continue;
13831391
}
1384-
if (this.processedExperimentalSettings.has(property)) {
1392+
if (!autoRefetch && this.processedExperimentalSettings.has(property)) {
13851393
continue;
13861394
}
13871395
this.processedExperimentalSettings.add(property);
1396+
if (schema.experiment.autoRefetch) {
1397+
this.autoRefetchExperimentalSettings.add(property);
1398+
}
13881399
try {
1389-
const value = await this.workbenchAssignmentService.getTreatment(`config.${property}`);
1400+
const value = await this.workbenchAssignmentService.getTreatment(schema.experiment.name ?? `config.${property}`);
13901401
if (!isUndefined(value) && !equals(value, schema.default)) {
13911402
overrides[property] = value;
13921403
}

0 commit comments

Comments
 (0)