From 6bc7ce6433f91c8f8f8e1f831ab62d0306126a2a Mon Sep 17 00:00:00 2001 From: Guy Waldman Date: Fri, 21 Sep 2018 02:01:10 +0300 Subject: [PATCH] Change behavior for non-text inputs * Added a new enum for setting types * Added separate `Delayer` with a long debounce for non-text inputs --- .../preferences/browser/settingsEditor2.ts | 33 ++++++++++++++----- .../parts/preferences/browser/settingsTree.ts | 10 +++--- .../preferences/browser/settingsTreeModels.ts | 30 ++++++++--------- .../preferences/common/preferences.ts | 15 ++++++++- .../preferences/common/preferencesModels.ts | 4 +-- 5 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts b/src/vs/workbench/parts/preferences/browser/settingsEditor2.ts index 5d1f58da749..5c37b187a78 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,12 +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_DEBOUNCE: number = 1000; + private static SETTING_UPDATE_FAST_DEBOUNCE: number = 1000; + private static SETTING_UPDATE_SLOW_DEBOUNCE: number = 200; private static readonly SUGGESTIONS: string[] = [ '@modified', '@tag:usesOnlineServices' ]; + private static shouldSettingUpdateFast(type: SettingValueType | SettingValueType[]): boolean { + if (isArray(type)) { + // nullable integer/number or complex + return true; + } + return type !== SettingValueType.Enum && type !== SettingValueType.Complex; + } + private defaultSettingsEditorModel: Settings2EditorModel; private rootElement: HTMLElement; @@ -89,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; @@ -127,7 +138,8 @@ export class SettingsEditor2 extends BaseEditor { this.viewState = { settingsTarget: ConfigurationTarget.USER }; this.delayRefreshOnLayout = new Delayer(100); - this.settingUpdateDelayer = new Delayer(SettingsEditor2.SETTING_UPDATE_DEBOUNCE); + 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); @@ -543,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); })); @@ -584,7 +596,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) { @@ -592,11 +604,16 @@ 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 _onDidBlurSetting(element: SettingsTreeSettingElement) { - this.settingUpdateDelayer.fire(); + this.settingFastUpdateDelayer.fire(); + this.settingSlowUpdateDelayer.fire(); } private updateTreeScrollSync(): void { diff --git a/src/vs/workbench/parts/preferences/browser/settingsTree.ts b/src/vs/workbench/parts/preferences/browser/settingsTree.ts index 73d1a4c9def..be947a2c0be 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 { @@ -387,7 +388,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 }); } return TPromise.wrap(null); @@ -918,7 +919,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 }); } })); @@ -1100,7 +1102,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 898f92865c8..a449db5aa11 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 baa3489c3f7..b5874f50c98 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; @@ -50,7 +63,7 @@ export interface ISetting { deprecationMessage?: string; scope?: ConfigurationScope; - type?: string | string[]; + type?: SettingValueType | SettingValueType[]; enum?: string[]; enumDescriptions?: string[]; enumDescriptionsAreMarkdown?: boolean; diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 5ebf357c101..d38823c4a01 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -21,7 +21,7 @@ import { ConfigurationScope, Extensions, IConfigurationNode, IConfigurationPrope import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { Registry } from 'vs/platform/registry/common/platform'; import { EditorModel } from 'vs/workbench/common/editor'; -import { IFilterMetadata, IFilterResult, IGroupFilter, IKeybindingsEditorModel, ISearchResultGroup, ISetting, ISettingMatch, ISettingMatcher, ISettingsEditorModel, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; +import { IFilterMetadata, IFilterResult, IGroupFilter, IKeybindingsEditorModel, ISearchResultGroup, ISetting, ISettingMatch, ISettingMatcher, ISettingsEditorModel, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences'; export abstract class AbstractSettingsModel extends EditorModel { @@ -616,7 +616,7 @@ export class DefaultSettings extends Disposable { descriptionRanges: [], overrides, scope: prop.scope, - type: prop.type, + type: prop.type as SettingValueType, enum: prop.enum, enumDescriptions: prop.enumDescriptions || prop.markdownEnumDescriptions, enumDescriptionsAreMarkdown: !prop.enumDescriptions, -- GitLab