mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-26 09:45:54 +01:00
Settings editor - Attempt 1 at introducing parent to the tree data model
This commit is contained in:
@@ -11,8 +11,9 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { escapeRegExpCharacters } from 'vs/base/common/strings';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ITreeConfiguration, ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree';
|
||||
import { DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults';
|
||||
import 'vs/css!./media/settingsEditor2';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -29,14 +30,13 @@ import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant }
|
||||
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { EditorOptions, IEditor } from 'vs/workbench/common/editor';
|
||||
import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets';
|
||||
import { ISettingsEditorViewState, SearchResultIdx, SearchResultModel, SettingsAccessibilityProvider, SettingsDataSource, SettingsRenderer, SettingsTreeController, SettingsTreeFilter, TreeElement } from 'vs/workbench/parts/preferences/browser/settingsTree';
|
||||
import { tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout';
|
||||
import { ISettingsEditorViewState, SearchResultIdx, SearchResultModel, SettingsAccessibilityProvider, SettingsDataSource, SettingsRenderer, SettingsTreeController, SettingsTreeFilter, TreeElement, isTOCLeaf } from 'vs/workbench/parts/preferences/browser/settingsTree';
|
||||
import { TOCDataSource, TOCRenderer } from 'vs/workbench/parts/preferences/browser/tocTree';
|
||||
import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences';
|
||||
import { IPreferencesService, ISearchResult, ISetting, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput';
|
||||
import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels';
|
||||
import { tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout';
|
||||
import { escapeRegExpCharacters } from 'vs/base/common/strings';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
@@ -638,19 +638,25 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
export interface ITOCEntry<T> {
|
||||
id: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface ITOCGroupEntry<T> extends ITOCEntry<T> {
|
||||
children?: ITOCEntry<T>[];
|
||||
}
|
||||
|
||||
export interface ITOCLeafEntry<T> extends ITOCEntry<T> {
|
||||
settings?: T[];
|
||||
}
|
||||
|
||||
export type IRawTOCEntry = ITOCEntry<string>;
|
||||
export type IResolvedTOCEntry = ITOCEntry<ISetting>;
|
||||
export type IRawTOCEntry = ITOCGroupEntry<string> | ITOCLeafEntry<string>;
|
||||
export type IResolvedTOCEntry = ITOCGroupEntry<ISetting> | ITOCLeafEntry<ISetting>;
|
||||
|
||||
function resolveSettingsTree(tocData: IRawTOCEntry, defaultSettings: DefaultSettingsEditorModel): IResolvedTOCEntry {
|
||||
return _resolveSettingsTree(tocData, getAllSettings(defaultSettings));
|
||||
}
|
||||
|
||||
function _resolveSettingsTree(tocData: IRawTOCEntry, allSettings: Set<ISetting>): IResolvedTOCEntry {
|
||||
if (tocData.settings) {
|
||||
if (isTOCLeaf(tocData)) {
|
||||
return <IResolvedTOCEntry>{
|
||||
id: tocData.id,
|
||||
label: tocData.label,
|
||||
|
||||
@@ -25,8 +25,8 @@ import { editorActiveLinkForeground, registerColor } from 'vs/platform/theme/com
|
||||
import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler } from 'vs/platform/theme/common/styler';
|
||||
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets';
|
||||
import { IResolvedTOCEntry, ITOCGroupEntry, ITOCLeafEntry, ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsEditor2';
|
||||
import { ISearchResult, ISetting } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { IResolvedTOCEntry } from 'vs/workbench/parts/preferences/browser/settingsEditor2';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
@@ -56,6 +56,7 @@ export interface ISettingElement extends ITreeItem {
|
||||
type: TreeItemType.setting;
|
||||
setting: ISetting;
|
||||
|
||||
parent: IGroupElement | SearchResultModel;
|
||||
displayCategory: string;
|
||||
displayLabel: string;
|
||||
value: any;
|
||||
@@ -68,6 +69,7 @@ export interface ISettingElement extends ITreeItem {
|
||||
|
||||
export interface IGroupElement extends ITreeItem {
|
||||
type: TreeItemType.groupTitle;
|
||||
parent: IGroupElement | IResolvedTOCEntry;
|
||||
group: IResolvedTOCEntry;
|
||||
index: number;
|
||||
}
|
||||
@@ -92,16 +94,17 @@ export class SettingsDataSource implements IDataSource {
|
||||
@IConfigurationService private configurationService: IConfigurationService
|
||||
) { }
|
||||
|
||||
getGroupElement(group: IResolvedTOCEntry, index: number): IGroupElement {
|
||||
getGroupElement(group: IResolvedTOCEntry, parent: IGroupElement | IResolvedTOCEntry, index: number): IGroupElement {
|
||||
return <IGroupElement>{
|
||||
type: TreeItemType.groupTitle,
|
||||
group,
|
||||
parent,
|
||||
id: sanitizeElementId(group.id),
|
||||
index
|
||||
};
|
||||
}
|
||||
|
||||
getSettingElement(setting: ISetting, group: IResolvedTOCEntry): ISettingElement {
|
||||
getSettingElement(setting: ISetting, parent: IGroupElement | SearchResultModel, category: string): ISettingElement {
|
||||
const { isConfigured, inspected, targetSelector } = inspectSetting(setting.key, this.viewState.settingsTarget, this.configurationService);
|
||||
|
||||
const displayValue = isConfigured ? inspected[targetSelector] : inspected.default;
|
||||
@@ -114,10 +117,10 @@ export class SettingsDataSource implements IDataSource {
|
||||
overriddenScopeList.push(localize('user', "User"));
|
||||
}
|
||||
|
||||
const displayKeyFormat = settingKeyToDisplayFormat(setting.key, group);
|
||||
const displayKeyFormat = settingKeyToDisplayFormat(setting.key, category);
|
||||
return <ISettingElement>{
|
||||
type: TreeItemType.setting,
|
||||
parent: group,
|
||||
parent,
|
||||
id: sanitizeElementId(setting.key),
|
||||
setting,
|
||||
|
||||
@@ -139,7 +142,7 @@ export class SettingsDataSource implements IDataSource {
|
||||
}
|
||||
|
||||
hasChildren(tree: ITree, element: TreeElementOrRoot): boolean {
|
||||
if (isRoot(element)) {
|
||||
if (isTOCRoot(element)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -154,36 +157,44 @@ export class SettingsDataSource implements IDataSource {
|
||||
return false;
|
||||
}
|
||||
|
||||
_getChildren(element: TreeElementOrRoot): TreeElement[] {
|
||||
if (isRoot(element)) {
|
||||
private _getChildren(element: TreeElementOrRoot): TreeElement[] {
|
||||
if (isTOCRoot(element)) {
|
||||
return this.getRootChildren(element);
|
||||
} else if (element instanceof SearchResultModel) {
|
||||
return this.getGroupChildren(element.resultsAsGroup());
|
||||
return this.getSearchResultChildren(element);
|
||||
} else if (element.type === TreeItemType.groupTitle) {
|
||||
return this.getGroupChildren(element.group);
|
||||
return this.getGroupChildren(element);
|
||||
} else {
|
||||
// No children...
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private getSearchResultChildren(searchResult: SearchResultModel): ISettingElement[] {
|
||||
return searchResult.getFlatSettings()
|
||||
.map(s => this.getSettingElement(s, searchResult, 'searchResult'));
|
||||
}
|
||||
|
||||
getChildren(tree: ITree, element: TreeElementOrRoot): TPromise<any, any> {
|
||||
return TPromise.as(this._getChildren(element));
|
||||
}
|
||||
|
||||
private getRootChildren(root: IResolvedTOCEntry): TreeElement[] {
|
||||
private getRootChildren(root: ITOCGroupEntry<ISetting>): TreeElement[] {
|
||||
return root.children
|
||||
.map((g, i) => this.getGroupElement(g, i));
|
||||
.map((g, i) => this.getGroupElement(g, root, i));
|
||||
}
|
||||
|
||||
private getGroupChildren(group: IResolvedTOCEntry): TreeElement[] {
|
||||
return group.children ?
|
||||
group.children.map((child, i) => this.getGroupElement(child, i)) :
|
||||
group.settings.map(s => this.getSettingElement(s, group));
|
||||
private getGroupChildren(groupElement: IGroupElement): TreeElement[] {
|
||||
return isTOCLeaf(groupElement.group) ?
|
||||
groupElement.group.settings.map(s => this.getSettingElement(s, groupElement, groupElement.id)) :
|
||||
groupElement.group.children.map((child, i) => this.getGroupElement(child, groupElement, i));
|
||||
}
|
||||
|
||||
getParent(tree: ITree, element: TreeElement): TPromise<any, any> {
|
||||
return TPromise.wrap(null);
|
||||
getParent(tree: ITree, element: TreeElementOrRoot): TPromise<any, any> {
|
||||
return TPromise.wrap(
|
||||
isTOCRoot(element) ? null :
|
||||
element instanceof SearchResultModel ? null :
|
||||
element.parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,11 +202,11 @@ function sanitizeElementId(id: string): string {
|
||||
return id.replace(/\./g, '_');
|
||||
}
|
||||
|
||||
function isRoot(element: TreeElementOrRoot): element is IResolvedTOCEntry {
|
||||
function isTOCRoot(element: TreeElementOrRoot): element is IResolvedTOCEntry {
|
||||
return element.id === 'root';
|
||||
}
|
||||
|
||||
export function settingKeyToDisplayFormat(key: string, group: IResolvedTOCEntry): { category: string, label: string } {
|
||||
export function settingKeyToDisplayFormat(key: string, groupId: string): { category: string, label: string } {
|
||||
let label = key
|
||||
.replace(/\.([a-z])/g, (match, p1) => `.${p1.toUpperCase()}`)
|
||||
.replace(/([a-z])([A-Z])/g, '$1 $2') // fooBar => foo Bar
|
||||
@@ -208,14 +219,14 @@ export function settingKeyToDisplayFormat(key: string, group: IResolvedTOCEntry)
|
||||
label = label.substr(lastDotIdx + 1);
|
||||
}
|
||||
|
||||
category = trimCategoryForGroup(category, group);
|
||||
category = trimCategoryForGroup(category, groupId);
|
||||
|
||||
return { category, label };
|
||||
}
|
||||
|
||||
function trimCategoryForGroup(category: string, group: IResolvedTOCEntry): string {
|
||||
function trimCategoryForGroup(category: string, groupId: string): string {
|
||||
const doTrim = forward => {
|
||||
const parts = group.id.split('.');
|
||||
const parts = groupId.split('.');
|
||||
while (parts.length) {
|
||||
const reg = new RegExp(`^${parts.join('\\.')}(\\.|$)`, 'i');
|
||||
if (reg.test(category)) {
|
||||
@@ -571,16 +582,16 @@ export class SettingsTreeFilter implements IFilter {
|
||||
return true;
|
||||
}
|
||||
|
||||
private groupHasConfiguredSetting(group: IResolvedTOCEntry): boolean {
|
||||
if (group.children) {
|
||||
return group.children.some(c => this.groupHasConfiguredSetting(c));
|
||||
}
|
||||
|
||||
for (let setting of group.settings) {
|
||||
const { isConfigured } = inspectSetting(setting.key, this.viewState.settingsTarget, this.configurationService);
|
||||
if (isConfigured) {
|
||||
return true;
|
||||
private groupHasConfiguredSetting(element: IResolvedTOCEntry): boolean {
|
||||
if (isTOCLeaf(element)) {
|
||||
for (let setting of element.settings) {
|
||||
const { isConfigured } = inspectSetting(setting.key, this.viewState.settingsTarget, this.configurationService);
|
||||
if (isConfigured) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return element.children.some(c => this.groupHasConfiguredSetting(c));
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -658,7 +669,7 @@ export class SearchResultModel {
|
||||
this.rawSearchResults[type] = result;
|
||||
}
|
||||
|
||||
resultsAsGroup(): IResolvedTOCEntry {
|
||||
getFlatSettings(): ISetting[] {
|
||||
const flatSettings: ISetting[] = [];
|
||||
this.getUniqueResults()
|
||||
.filter(r => !!r)
|
||||
@@ -667,10 +678,10 @@ export class SearchResultModel {
|
||||
...r.filterMatches.map(m => m.setting));
|
||||
});
|
||||
|
||||
return <IResolvedTOCEntry>{
|
||||
id: 'settingsSearchResultGroup',
|
||||
settings: flatSettings,
|
||||
label: 'searchResults'
|
||||
};
|
||||
return flatSettings;
|
||||
}
|
||||
}
|
||||
|
||||
export function isTOCLeaf<T>(entry: ITOCEntry<T>): entry is ITOCLeafEntry<T> {
|
||||
return !!(<ITOCLeafEntry<T>>entry).settings;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDataSource, IRenderer, ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { IResolvedTOCEntry } from 'vs/workbench/parts/preferences/browser/settingsEditor2';
|
||||
import { IResolvedTOCEntry, ITOCGroupEntry } from 'vs/workbench/parts/preferences/browser/settingsEditor2';
|
||||
import { ISetting } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { isTOCLeaf } from 'vs/workbench/parts/preferences/browser/settingsTree';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
@@ -21,10 +23,10 @@ export class TOCDataSource implements IDataSource {
|
||||
}
|
||||
|
||||
hasChildren(tree: ITree, element: IResolvedTOCEntry): boolean {
|
||||
return element.children && element.children.length && typeof element.children[0] !== 'string';
|
||||
return !isTOCLeaf(element) && element.children.length && typeof element.children[0] !== 'string';
|
||||
}
|
||||
|
||||
getChildren(tree: ITree, element: IResolvedTOCEntry): TPromise<IResolvedTOCEntry[], any> {
|
||||
getChildren(tree: ITree, element: ITOCGroupEntry<ISetting>): TPromise<IResolvedTOCEntry[], any> {
|
||||
return TPromise.as(<IResolvedTOCEntry[]>element.children);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user