diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 4baf07d86be97..6f184394d2c61 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts @@ -8,6 +8,7 @@ import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar'; import { Action } from 'vs/base/common/actions'; import * as arrays from 'vs/base/common/arrays'; +import { isArray } from 'vs/base/common/types'; import { Delayer, ThrottledDelayer } from 'vs/base/common/async'; import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation'; import * as collections from 'vs/base/common/collections'; @@ -43,7 +44,7 @@ import { ISettingsEditorViewState, MODIFIED_SETTING_TAG, ONLINE_SERVICES_SETTING import { settingsTextInputBorder } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { TOCRenderer, TOCTree, TOCTreeModel } from 'vs/workbench/parts/preferences/browser/tocTree'; import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IPreferencesSearchService, ISearchProvider, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/parts/preferences/common/preferences'; -import { IPreferencesService, ISearchResult, ISettingsEditorModel, ISettingsEditorOptions, SettingsEditorOptions } from 'vs/workbench/services/preferences/common/preferences'; +import { IPreferencesService, ISearchResult, ISettingsEditorModel, ISettingsEditorOptions, SettingsEditorOptions, SettingValueType } from 'vs/workbench/services/preferences/common/preferences'; import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput'; import { Settings2EditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; @@ -53,11 +54,21 @@ export class SettingsEditor2 extends BaseEditor { public static readonly ID: string = 'workbench.editor.settings2'; private static NUM_INSTANCES: number = 0; + private static SETTING_UPDATE_FAST_DEBOUNCE: number = 200; + private static SETTING_UPDATE_SLOW_DEBOUNCE: number = 1000; private static readonly SUGGESTIONS: string[] = [ '@modified', '@tag:usesOnlineServices' ]; + private static shouldSettingUpdateFast(type: SettingValueType | SettingValueType[]): boolean { + if (isArray(type)) { + // nullable integer/number or complex + return false; + } + return type === SettingValueType.Enum || type === SettingValueType.Complex; + } + private defaultSettingsEditorModel: Settings2EditorModel; private rootElement: HTMLElement; @@ -88,7 +99,8 @@ export class SettingsEditor2 extends BaseEditor { private delayRefreshOnLayout: Delayer; private lastLayedoutWidth: number; - private settingUpdateDelayer: Delayer; + private settingFastUpdateDelayer: Delayer; + private settingSlowUpdateDelayer: Delayer; private pendingSettingUpdate: { key: string, value: any }; private viewState: ISettingsEditorViewState; @@ -126,7 +138,8 @@ export class SettingsEditor2 extends BaseEditor { this.viewState = { settingsTarget: ConfigurationTarget.USER }; this.delayRefreshOnLayout = new Delayer(100); - this.settingUpdateDelayer = new Delayer(200); + this.settingFastUpdateDelayer = new Delayer(SettingsEditor2.SETTING_UPDATE_FAST_DEBOUNCE); + this.settingSlowUpdateDelayer = new Delayer(SettingsEditor2.SETTING_UPDATE_SLOW_DEBOUNCE); this.inSettingsEditorContextKey = CONTEXT_SETTINGS_EDITOR.bindTo(contextKeyService); this.searchFocusContextKey = CONTEXT_SETTINGS_SEARCH_FOCUS.bindTo(contextKeyService); @@ -542,7 +555,7 @@ export class SettingsEditor2 extends BaseEditor { labelDiv.setAttribute('aria-label', ''); this.settingsTreeRenderer = this.instantiationService.createInstance(SettingsRenderer, this.settingsTreeContainer); - this._register(this.settingsTreeRenderer.onDidChangeSetting(e => this.onDidChangeSetting(e.key, e.value))); + this._register(this.settingsTreeRenderer.onDidChangeSetting(e => this.onDidChangeSetting(e.key, e.value, e.type))); this._register(this.settingsTreeRenderer.onDidOpenSettings(settingKey => { this.openSettingsFile(settingKey); })); @@ -580,7 +593,7 @@ export class SettingsEditor2 extends BaseEditor { } } - private onDidChangeSetting(key: string, value: any): void { + private onDidChangeSetting(key: string, value: any, type: SettingValueType | SettingValueType[]): void { this.notifyNoSaveNeeded(false); if (this.pendingSettingUpdate && this.pendingSettingUpdate.key !== key) { @@ -588,7 +601,11 @@ export class SettingsEditor2 extends BaseEditor { } this.pendingSettingUpdate = { key, value }; - this.settingUpdateDelayer.trigger(() => this.updateChangedSetting(key, value)); + if (SettingsEditor2.shouldSettingUpdateFast(type)) { + this.settingFastUpdateDelayer.trigger(() => this.updateChangedSetting(key, value)); + } else { + this.settingSlowUpdateDelayer.trigger(() => this.updateChangedSetting(key, value)); + } } private updateTreeScrollSync(): void { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 53ede5124bd21..0b920918bb343 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTree.ts @@ -43,7 +43,7 @@ import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsLayout import { ISettingsEditorViewState, isExcludeSetting, settingKeyToDisplayFormat, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/parts/preferences/browser/settingsTreeModels'; import { ExcludeSettingWidget, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/parts/preferences/browser/settingsWidgets'; import { SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/parts/preferences/common/preferences'; -import { ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; +import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences'; const $ = DOM.$; @@ -331,6 +331,7 @@ const SETTINGS_GROUP_ELEMENT_TEMPLATE_ID = 'settings.group.template'; export interface ISettingChangeEvent { key: string; value: any; // undefined => reset/unconfigure + type: SettingValueType | SettingValueType[]; } export interface ISettingLinkClickEvent { @@ -384,7 +385,7 @@ export class SettingsRenderer implements ITreeRenderer { this.settingActions = [ new Action('settings.resetSetting', localize('resetSettingLabel', "Reset Setting"), undefined, undefined, (context: SettingsTreeSettingElement) => { if (context) { - this._onDidChangeSetting.fire({ key: context.setting.key, value: undefined }); + this._onDidChangeSetting.fire({ key: context.setting.key, value: undefined, type: context.setting.type as SettingValueType }); } return TPromise.wrap(null); @@ -913,7 +914,8 @@ export class SettingsRenderer implements ITreeRenderer { this._onDidChangeSetting.fire({ key: template.context.setting.key, - value: Object.keys(newValue).length === 0 ? undefined : sortKeys(newValue) + value: Object.keys(newValue).length === 0 ? undefined : sortKeys(newValue), + type: template.context.valueType }); } })); @@ -1095,7 +1097,7 @@ export class SettingsRenderer implements ITreeRenderer { } private renderValue(element: SettingsTreeSettingElement, templateId: string, template: ISettingItemTemplate | ISettingBoolItemTemplate): void { - const onChange = value => this._onDidChangeSetting.fire({ key: element.setting.key, value }); + const onChange = value => this._onDidChangeSetting.fire({ key: element.setting.key, value, type: template.context.valueType }); template.deprecationWarningElement.innerText = element.setting.deprecationMessage || ''; if (templateId === SETTINGS_ENUM_TEMPLATE_ID) { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts index 898f92865c8ae..a449db5aa11f8 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsTreeModels.ts @@ -11,7 +11,7 @@ import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configur import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets'; import { ITOCEntry, knownAcronyms } from 'vs/workbench/parts/preferences/browser/settingsLayout'; -import { IExtensionSetting, ISearchResult, ISetting } from 'vs/workbench/services/preferences/common/preferences'; +import { IExtensionSetting, ISearchResult, ISetting, SettingValueType } from 'vs/workbench/services/preferences/common/preferences'; export const MODIFIED_SETTING_TAG = 'modified'; export const ONLINE_SERVICES_SETTING_TAG = 'usesOnlineServices'; @@ -99,7 +99,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { tags?: Set; overriddenScopeList: string[]; description: string; - valueType: 'enum' | 'string' | 'integer' | 'number' | 'boolean' | 'exclude' | 'complex' | 'nullable-integer' | 'nullable-number'; + valueType: SettingValueType; constructor(setting: ISetting, parent: SettingsTreeGroupElement, index: number, inspectResult: IInspectResult) { super(); @@ -167,27 +167,27 @@ export class SettingsTreeSettingElement extends SettingsTreeElement { this.description = this.setting.description.join('\n'); if (this.setting.enum && (!this.setting.type || settingTypeEnumRenderable(this.setting.type))) { - this.valueType = 'enum'; + this.valueType = SettingValueType.Enum; } else if (this.setting.type === 'string') { - this.valueType = 'string'; + this.valueType = SettingValueType.String; } else if (isExcludeSetting(this.setting)) { - this.valueType = 'exclude'; + this.valueType = SettingValueType.Exclude; } else if (this.setting.type === 'integer') { - this.valueType = 'integer'; + this.valueType = SettingValueType.Integer; } else if (this.setting.type === 'number') { - this.valueType = 'number'; + this.valueType = SettingValueType.Number; } else if (this.setting.type === 'boolean') { - this.valueType = 'boolean'; - } else if (isArray(this.setting.type) && this.setting.type.indexOf('null') > -1 && this.setting.type.length === 2) { - if (this.setting.type.indexOf('integer') > -1) { - this.valueType = 'nullable-integer'; - } else if (this.setting.type.indexOf('number') > -1) { - this.valueType = 'nullable-number'; + this.valueType = SettingValueType.Boolean; + } else if (isArray(this.setting.type) && this.setting.type.indexOf(SettingValueType.Null) > -1 && this.setting.type.length === 2) { + if (this.setting.type.indexOf(SettingValueType.Integer) > -1) { + this.valueType = SettingValueType.NullableInteger; + } else if (this.setting.type.indexOf(SettingValueType.Number) > -1) { + this.valueType = SettingValueType.NullableNumber; } else { - this.valueType = 'complex'; + this.valueType = SettingValueType.Complex; } } else { - this.valueType = 'complex'; + this.valueType = SettingValueType.Complex; } } diff --git a/src/vs/workbench/services/preferences/common/preferences.ts b/src/vs/workbench/services/preferences/common/preferences.ts index baa3489c3f7ae..80453e0f3cf7f 100644 --- a/src/vs/workbench/services/preferences/common/preferences.ts +++ b/src/vs/workbench/services/preferences/common/preferences.ts @@ -21,6 +21,19 @@ import { IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsSer import { Settings2EditorModel } from 'vs/workbench/services/preferences/common/preferencesModels'; import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry'; +export enum SettingValueType { + Null = 'null', + Enum = 'enum', + String = 'string', + Integer = 'integer', + Number = 'number', + Boolean = 'boolean', + Exclude = 'exclude', + Complex = 'complex', + NullableInteger = 'nullable-integer', + NullableNumber = 'nullable-number' +} + export interface ISettingsGroup { id: string; range: IRange;