mirror of https://github.com/microsoft/vscode.git
parent
b37c013d08
commit
040ac30020
|
@ -115,31 +115,46 @@ const editorConfiguration: IConfigurationNode = {
|
|||
type: 'boolean',
|
||||
default: false,
|
||||
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."),
|
||||
tags: ['experimental', 'onExP']
|
||||
tags: ['experimental'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
'editor.experimental.preferTreeSitter.css': {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
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."),
|
||||
tags: ['experimental', 'onExP']
|
||||
tags: ['experimental'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
'editor.experimental.preferTreeSitter.typescript': {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
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."),
|
||||
tags: ['experimental', 'onExP']
|
||||
tags: ['experimental'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
'editor.experimental.preferTreeSitter.ini': {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
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."),
|
||||
tags: ['experimental', 'onExP']
|
||||
tags: ['experimental'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
'editor.experimental.preferTreeSitter.regex': {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
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."),
|
||||
tags: ['experimental', 'onExP']
|
||||
tags: ['experimental'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
'editor.language.brackets': {
|
||||
type: ['array', 'null'],
|
||||
|
|
|
@ -4468,14 +4468,20 @@ class InlineEditorSuggest extends BaseEditorOption<EditorOption.inlineSuggest, I
|
|||
'editor.inlineSuggest.experimental.suppressInlineSuggestions': {
|
||||
type: 'string',
|
||||
default: defaults.experimental.suppressInlineSuggestions,
|
||||
tags: ['experimental', 'onExp'],
|
||||
description: nls.localize('inlineSuggest.suppressInlineSuggestions', "Suppresses inline completions for specified extension IDs -- comma separated.")
|
||||
tags: ['experimental'],
|
||||
description: nls.localize('inlineSuggest.suppressInlineSuggestions', "Suppresses inline completions for specified extension IDs -- comma separated."),
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
'editor.inlineSuggest.experimental.triggerCommandOnProviderChange': {
|
||||
type: 'boolean',
|
||||
default: defaults.experimental.triggerCommandOnProviderChange,
|
||||
tags: ['experimental', 'onExp'],
|
||||
description: nls.localize('inlineSuggest.triggerCommandOnProviderChange', "Controls whether to trigger a command when the inline suggestion provider changes.")
|
||||
tags: ['experimental'],
|
||||
description: nls.localize('inlineSuggest.triggerCommandOnProviderChange', "Controls whether to trigger a command when the inline suggestion provider changes."),
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
'editor.inlineSuggest.fontFamily': {
|
||||
type: 'string',
|
||||
|
@ -6328,7 +6334,9 @@ export const EditorOptions = {
|
|||
10, 0, Constants.MAX_SAFE_SMALL_INTEGER,
|
||||
{
|
||||
description: nls.localize('quickSuggestionsDelay', "Controls the delay in milliseconds after which quick suggestions will show up."),
|
||||
tags: ['onExP']
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
}
|
||||
)),
|
||||
readOnly: register(new EditorBooleanOption(
|
||||
|
|
|
@ -176,7 +176,6 @@ export interface IConfigurationPropertySchema extends IJSONSchema {
|
|||
* List of tags associated to the property.
|
||||
* - A tag can be used for filtering
|
||||
* - Use `experimental` tag for marking the setting as experimental.
|
||||
* - Use `onExP` tag for marking that the default of the setting can be changed by running experiments.
|
||||
*/
|
||||
tags?: string[];
|
||||
|
||||
|
@ -217,6 +216,23 @@ export interface IConfigurationPropertySchema extends IJSONSchema {
|
|||
* a system-wide policy.
|
||||
*/
|
||||
policy?: IPolicy;
|
||||
|
||||
/**
|
||||
* When specified, this setting's default value can always be overwritten by
|
||||
* an experiment.
|
||||
*/
|
||||
experiment?: {
|
||||
/**
|
||||
* Whether to automatically refetch the experiment data and
|
||||
* update the configuration.
|
||||
*/
|
||||
autoRefetch: boolean;
|
||||
|
||||
/**
|
||||
* The name of the experiment. By default, this is `config.${settingId}`
|
||||
*/
|
||||
name?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface IExtensionInfo {
|
||||
|
@ -657,6 +673,11 @@ class ConfigurationRegistry extends Disposable implements IConfigurationRegistry
|
|||
property.restricted = types.isUndefinedOrNull(property.restricted) ? !!restrictedProperties?.includes(key) : property.restricted;
|
||||
}
|
||||
|
||||
if (property.experiment) {
|
||||
property.tags = property.tags ?? [];
|
||||
property.tags.push('onExP');
|
||||
}
|
||||
|
||||
const excluded = properties[key].hasOwnProperty('included') && !properties[key].included;
|
||||
const policyName = properties[key].policy?.name;
|
||||
|
||||
|
@ -679,6 +700,7 @@ class ConfigurationRegistry extends Disposable implements IConfigurationRegistry
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
const subNodes = configuration.allOf;
|
||||
|
|
|
@ -271,6 +271,11 @@ configurationExtPoint.setHandler((extensions, { added, removed }) => {
|
|||
if (extensionConfigurationPolicy?.[key]) {
|
||||
propertyConfiguration.policy = extensionConfigurationPolicy?.[key];
|
||||
}
|
||||
if (propertyConfiguration.tags?.some(tag => tag.toLowerCase() === 'onexp')) {
|
||||
propertyConfiguration.experiment = {
|
||||
autoRefetch: false
|
||||
};
|
||||
}
|
||||
seenProperties.add(key);
|
||||
propertyConfiguration.scope = propertyConfiguration.scope ? parseScope(propertyConfiguration.scope.toString()) : ConfigurationScope.WINDOW;
|
||||
}
|
||||
|
|
|
@ -538,7 +538,9 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
|
|||
'type': 'string',
|
||||
'enum': ['hidden', 'visibleInWorkspace', 'visible', 'maximizedInWorkspace', 'maximized'],
|
||||
'default': 'hidden',
|
||||
'tags': ['onExp'],
|
||||
'experiment': {
|
||||
autoRefetch: false
|
||||
},
|
||||
'description': localize('secondarySideBarDefaultVisibility', "Controls the default visibility of the secondary side bar in workspaces or empty windows opened for the first time."),
|
||||
'enumDescriptions': [
|
||||
localize('workbench.secondarySideBar.defaultVisibility.hidden', "The secondary side bar is hidden by default."),
|
||||
|
@ -626,7 +628,10 @@ const registry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Con
|
|||
'type': 'boolean',
|
||||
'default': product.quality !== 'stable',
|
||||
'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."),
|
||||
'tags': ['experimental', 'onExP']
|
||||
'tags': ['experimental'],
|
||||
'experiment': {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
'workbench.hover.delay': {
|
||||
'type': 'number',
|
||||
|
|
|
@ -260,13 +260,19 @@ configurationRegistry.registerConfiguration({
|
|||
type: 'string',
|
||||
enum: ['inline', 'hover', 'input', 'none'],
|
||||
default: 'inline',
|
||||
tags: ['experimental', 'onExp'],
|
||||
tags: ['experimental'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
'chat.emptyChatState.enabled': {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: nls.localize('chat.emptyChatState', "Shows a modified empty chat state with hints in the input placeholder text."),
|
||||
tags: ['experimental', 'onExp'],
|
||||
tags: ['experimental'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
'chat.checkpoints.enabled': {
|
||||
type: 'boolean',
|
||||
|
@ -321,7 +327,9 @@ configurationRegistry.registerConfiguration({
|
|||
type: 'boolean',
|
||||
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."),
|
||||
default: true,
|
||||
tags: ['onExp'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
[ChatConfiguration.ExtensionToolsEnabled]: {
|
||||
type: 'boolean',
|
||||
|
@ -337,7 +345,9 @@ configurationRegistry.registerConfiguration({
|
|||
type: 'boolean',
|
||||
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'),
|
||||
default: true,
|
||||
tags: ['onExp'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
},
|
||||
policy: {
|
||||
name: 'ChatAgentMode',
|
||||
minimumVersion: '1.99',
|
||||
|
@ -499,7 +509,10 @@ configurationRegistry.registerConfiguration({
|
|||
enum: ['default', 'apple'],
|
||||
description: nls.localize('chat.signInDialogVariant', "Control variations of the sign-in dialog."),
|
||||
default: 'default',
|
||||
tags: ['onExp', 'experimental']
|
||||
tags: ['experimental'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -35,7 +35,10 @@ configurationRegistry.registerConfiguration({
|
|||
markdownDescription: localize('telemetry.editStats.detailed.enabled', "Controls whether to enable telemetry for detailed edit statistics (only sends statistics if general telemetry is enabled)."),
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
tags: ['experimental', 'onExP'],
|
||||
tags: ['experimental'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
[EDIT_TELEMETRY_SHOW_STATUS_BAR]: {
|
||||
markdownDescription: localize('telemetry.editStats.showStatusBar', "Controls whether to show the status bar for edit telemetry."),
|
||||
|
|
|
@ -63,13 +63,19 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat
|
|||
description: localize('enableV2', "Whether to use the next version of inline chat."),
|
||||
default: false,
|
||||
type: 'boolean',
|
||||
tags: ['preview', 'onExp'],
|
||||
tags: ['preview'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
[InlineChatConfigKeys.HideOnRequest]: {
|
||||
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."),
|
||||
default: false,
|
||||
type: 'boolean',
|
||||
tags: ['preview', 'onExp'],
|
||||
tags: ['preview'],
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
|
|
|
@ -40,8 +40,11 @@ Registry.as<IConfigurationRegistry>(ConfigExt.Configuration).registerConfigurati
|
|||
'application.experimental.rendererProfiling': {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
tags: ['experimental', 'onExP'],
|
||||
markdownDescription: localize('experimental.rendererProfiling', "When enabled, slow renderers are automatically profiled.")
|
||||
tags: ['experimental'],
|
||||
markdownDescription: localize('experimental.rendererProfiling', "When enabled, slow renderers are automatically profiled."),
|
||||
experiment: {
|
||||
autoRefetch: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ import { Event, Emitter } from '../../../../base/common/event.js';
|
|||
import { ResourceMap } from '../../../../base/common/map.js';
|
||||
import { equals } from '../../../../base/common/objects.js';
|
||||
import { Disposable, DisposableStore } from '../../../../base/common/lifecycle.js';
|
||||
import { Queue, Barrier, Promises, Delayer } from '../../../../base/common/async.js';
|
||||
import { Queue, Barrier, Promises, Delayer, RunOnceScheduler } from '../../../../base/common/async.js';
|
||||
import { IJSONContributionRegistry, Extensions as JSONExtensions } from '../../../../platform/jsonschemas/common/jsonContributionRegistry.js';
|
||||
import { IWorkspaceContextService, Workspace as BaseWorkspace, WorkbenchState, IWorkspaceFolder, IWorkspaceFoldersChangeEvent, WorkspaceFolder, toWorkspaceFolder, isWorkspaceFolder, IWorkspaceFoldersWillChangeEvent, IEmptyWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier, IWorkspaceIdentifier, IAnyWorkspaceIdentifier } from '../../../../platform/workspace/common/workspace.js';
|
||||
import { ConfigurationModel, ConfigurationChangeEvent, mergeChanges } from '../../../../platform/configuration/common/configurationModels.js';
|
||||
|
@ -47,6 +47,7 @@ import { IBrowserWorkbenchEnvironmentService } from '../../environment/browser/e
|
|||
import { workbenchConfigurationNodeBase } from '../../../common/configuration.js';
|
||||
import { mainWindow } from '../../../../base/browser/window.js';
|
||||
import { runWhenWindowIdle } from '../../../../base/browser/dom.js';
|
||||
import { ASSIGNMENT_REFETCH_INTERVAL } from '../../../../platform/assignment/common/assignment.js';
|
||||
|
||||
function getLocalUserConfigurationScopes(userDataProfile: IUserDataProfile, hasRemote: boolean): ConfigurationScope[] | undefined {
|
||||
const isDefaultProfile = userDataProfile.isDefault || userDataProfile.useDefaultFlags?.settings;
|
||||
|
@ -1338,7 +1339,9 @@ class ConfigurationDefaultOverridesContribution extends Disposable implements IW
|
|||
static readonly ID = 'workbench.contrib.configurationDefaultOverridesContribution';
|
||||
|
||||
private readonly processedExperimentalSettings = new Set<string>();
|
||||
private readonly autoRefetchExperimentalSettings = new Set<string>();
|
||||
private readonly configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
|
||||
private readonly autoRefetchExperimentalSettingsScheduler: RunOnceScheduler;
|
||||
|
||||
constructor(
|
||||
@IWorkbenchAssignmentService private readonly workbenchAssignmentService: IWorkbenchAssignmentService,
|
||||
|
@ -1348,17 +1351,23 @@ class ConfigurationDefaultOverridesContribution extends Disposable implements IW
|
|||
) {
|
||||
super();
|
||||
|
||||
this.autoRefetchExperimentalSettingsScheduler = new RunOnceScheduler(() => {
|
||||
this.processExperimentalSettings(this.autoRefetchExperimentalSettings, true);
|
||||
this.autoRefetchExperimentalSettingsScheduler.schedule();
|
||||
}, ASSIGNMENT_REFETCH_INTERVAL);
|
||||
|
||||
this.updateDefaults();
|
||||
|
||||
// When configuration is updated make sure to apply experimental configuration overrides
|
||||
this._register(this.configurationRegistry.onDidUpdateConfiguration(({ properties }) => this.processExperimentalSettings(properties)));
|
||||
this._register(this.configurationRegistry.onDidUpdateConfiguration(({ properties }) => this.processExperimentalSettings(properties, false)));
|
||||
|
||||
}
|
||||
|
||||
private async updateDefaults(): Promise<void> {
|
||||
this.logService.trace('ConfigurationService#updateDefaults: begin');
|
||||
try {
|
||||
// Check for experiments
|
||||
await this.processExperimentalSettings(Object.keys(this.configurationRegistry.getConfigurationProperties()));
|
||||
await this.processExperimentalSettings(Object.keys(this.configurationRegistry.getConfigurationProperties()), false);
|
||||
} finally {
|
||||
// Invalidate defaults cache after extensions have registered
|
||||
// and after the experiments have been resolved to prevent
|
||||
|
@ -1367,26 +1376,28 @@ class ConfigurationDefaultOverridesContribution extends Disposable implements IW
|
|||
this.logService.trace('ConfigurationService#updateDefaults: resetting the defaults');
|
||||
this.configurationService.reloadConfiguration(ConfigurationTarget.DEFAULT);
|
||||
}
|
||||
|
||||
// Schedule auto-refetch of experimental settings
|
||||
this.autoRefetchExperimentalSettingsScheduler.schedule();
|
||||
}
|
||||
|
||||
private async processExperimentalSettings(properties: Iterable<string>): Promise<void> {
|
||||
private async processExperimentalSettings(properties: Iterable<string>, autoRefetch: boolean): Promise<void> {
|
||||
const overrides: IStringDictionary<any> = {};
|
||||
const allProperties = this.configurationRegistry.getConfigurationProperties();
|
||||
for (const property of properties) {
|
||||
const schema = allProperties[property];
|
||||
const tags = schema?.tags;
|
||||
// Many experimental settings refer to in-development or unstable settings.
|
||||
// onExP more clearly indicates that the setting could be
|
||||
// part of an experiment.
|
||||
if (!tags || !tags.some(tag => tag.toLowerCase() === 'onexp')) {
|
||||
if (!schema.experiment) {
|
||||
continue;
|
||||
}
|
||||
if (this.processedExperimentalSettings.has(property)) {
|
||||
if (!autoRefetch && this.processedExperimentalSettings.has(property)) {
|
||||
continue;
|
||||
}
|
||||
this.processedExperimentalSettings.add(property);
|
||||
if (schema.experiment.autoRefetch) {
|
||||
this.autoRefetchExperimentalSettings.add(property);
|
||||
}
|
||||
try {
|
||||
const value = await this.workbenchAssignmentService.getTreatment(`config.${property}`);
|
||||
const value = await this.workbenchAssignmentService.getTreatment(schema.experiment.name ?? `config.${property}`);
|
||||
if (!isUndefined(value) && !equals(value, schema.default)) {
|
||||
overrides[property] = value;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue