mirror of
https://github.com/Microsoft/vscode
synced 2024-09-19 02:26:04 +00:00
Merge branch 'master' of github.com:Microsoft/vscode
This commit is contained in:
commit
438906d261
|
@ -3,105 +3,105 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-item-value > .setting-item-control {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-item-value > .setting-item-control {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-value {
|
||||
margin-right: 3px;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-pattern,
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-value,
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-sibling {
|
||||
display: inline-block;
|
||||
line-height: 22px;
|
||||
font-family: var(--monaco-monospace-font);
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-sibling {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-sibling {
|
||||
opacity: 0.7;
|
||||
margin-left: 0.5em;
|
||||
font-size: 0.9em;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row .monaco-action-bar {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:focus {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover .monaco-action-bar,
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected .monaco-action-bar {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row:hover .monaco-action-bar,
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row.selected .monaco-action-bar {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .action-label {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row .monaco-action-bar .action-label {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .setting-excludeAction-edit {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row .monaco-action-bar .setting-listAction-edit {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .setting-excludeAction-edit {
|
||||
.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row .monaco-action-bar .setting-listAction-edit {
|
||||
background: url("edit-light.svg") center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .setting-excludeAction-edit {
|
||||
.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row .monaco-action-bar .setting-listAction-edit {
|
||||
background: url("edit-dark.svg") center center no-repeat;
|
||||
}
|
||||
|
||||
.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .setting-excludeAction-remove {
|
||||
.vs .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row .monaco-action-bar .setting-listAction-remove {
|
||||
background: url("remove-light.svg") center center no-repeat;
|
||||
}
|
||||
|
||||
.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row .monaco-action-bar .setting-excludeAction-remove {
|
||||
.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row .monaco-action-bar .setting-listAction-remove {
|
||||
background: url("remove-dark.svg") center center no-repeat;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .monaco-text-button {
|
||||
width: initial;
|
||||
padding: 2px 14px;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-item-control.setting-exclude-new-mode .setting-exclude-new-row {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-item-control.setting-list-new-mode .setting-list-new-row {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .monaco-text-button.setting-exclude-addButton {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .monaco-text-button.setting-list-addButton {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-edit-row {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-edit-row {
|
||||
display: flex
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-patternInput,
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-siblingInput {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-valueInput,
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-siblingInput {
|
||||
height: 22px;
|
||||
max-width: 320px;
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-okButton {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-okButton {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-widget {
|
||||
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ export class SettingsEditor2 extends BaseEditor {
|
|||
return false;
|
||||
}
|
||||
return type === SettingValueType.Enum ||
|
||||
type === SettingValueType.ArrayOfString ||
|
||||
type === SettingValueType.Complex ||
|
||||
type === SettingValueType.Boolean ||
|
||||
type === SettingValueType.Exclude;
|
||||
|
@ -968,7 +969,7 @@ export class SettingsEditor2 extends BaseEditor {
|
|||
if (key) {
|
||||
const focusedKey = focusedSetting.getAttribute(AbstractSettingRenderer.SETTING_KEY_ATTR);
|
||||
if (focusedKey === key &&
|
||||
!DOM.hasClass(focusedSetting, 'setting-item-exclude')) { // update `exclude`s live, as they have a separate "submit edit" step built in before this
|
||||
!DOM.hasClass(focusedSetting, 'setting-item-list')) { // update `list`s live, as they have a separate "submit edit" step built in before this
|
||||
|
||||
this.updateModifiedLabelForKey(key);
|
||||
this.scheduleRefresh(focusedSetting, key);
|
||||
|
|
|
@ -42,14 +42,15 @@ import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attach
|
|||
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { ITOCEntry } from 'vs/workbench/contrib/preferences/browser/settingsLayout';
|
||||
import { ISettingsEditorViewState, settingKeyToDisplayFormat, SettingsTreeElement, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels';
|
||||
import { ExcludeSettingWidget, IExcludeChangeEvent, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
|
||||
import { ListSettingWidget, IListChangeEvent, IListDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, ExcludeSettingWidget } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
|
||||
import { SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences';
|
||||
import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { isArray } from 'vs/base/common/types';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
function getExcludeDisplayValue(element: SettingsTreeSettingElement): IExcludeDataItem[] {
|
||||
function getExcludeDisplayValue(element: SettingsTreeSettingElement): IListDataItem[] {
|
||||
const data = element.isConfigured ?
|
||||
{ ...element.defaultValue, ...element.scopeValue } :
|
||||
element.defaultValue;
|
||||
|
@ -62,12 +63,20 @@ function getExcludeDisplayValue(element: SettingsTreeSettingElement): IExcludeDa
|
|||
|
||||
return {
|
||||
id: key,
|
||||
pattern: key,
|
||||
value: key,
|
||||
sibling
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getListDisplayValue(element: SettingsTreeSettingElement): IListDataItem[] {
|
||||
return element.value.map((key: string) => {
|
||||
return {
|
||||
value: key
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function resolveSettingsTree(tocData: ITOCEntry, coreSettingsGroups: ISettingsGroup[]): { tree: ITOCEntry, leftoverSettings: Set<ISetting> } {
|
||||
const allSettings = getFlatSettings(coreSettingsGroups);
|
||||
return {
|
||||
|
@ -211,8 +220,12 @@ interface ISettingComplexItemTemplate extends ISettingItemTemplate<void> {
|
|||
button: Button;
|
||||
}
|
||||
|
||||
interface ISettingListItemTemplate extends ISettingItemTemplate<void> {
|
||||
listWidget: ListSettingWidget;
|
||||
}
|
||||
|
||||
interface ISettingExcludeItemTemplate extends ISettingItemTemplate<void> {
|
||||
excludeWidget: ExcludeSettingWidget;
|
||||
excludeWidget: ListSettingWidget;
|
||||
}
|
||||
|
||||
interface ISettingNewExtensionsTemplate extends IDisposableTemplate {
|
||||
|
@ -229,6 +242,7 @@ const SETTINGS_TEXT_TEMPLATE_ID = 'settings.text.template';
|
|||
const SETTINGS_NUMBER_TEMPLATE_ID = 'settings.number.template';
|
||||
const SETTINGS_ENUM_TEMPLATE_ID = 'settings.enum.template';
|
||||
const SETTINGS_BOOL_TEMPLATE_ID = 'settings.bool.template';
|
||||
const SETTINGS_ARRAY_TEMPLATE_ID = 'settings.array.template';
|
||||
const SETTINGS_EXCLUDE_TEMPLATE_ID = 'settings.exclude.template';
|
||||
const SETTINGS_COMPLEX_TEMPLATE_ID = 'settings.complex.template';
|
||||
const SETTINGS_NEW_EXTENSIONS_TEMPLATE_ID = 'settings.newExtensions.template';
|
||||
|
@ -656,11 +670,81 @@ export class SettingComplexRenderer extends AbstractSettingRenderer implements I
|
|||
}
|
||||
}
|
||||
|
||||
export class SettingArrayRenderer extends AbstractSettingRenderer implements ITreeRenderer<SettingsTreeSettingElement, never, ISettingListItemTemplate> {
|
||||
templateId = SETTINGS_ARRAY_TEMPLATE_ID;
|
||||
|
||||
renderTemplate(container: HTMLElement): ISettingListItemTemplate {
|
||||
const common = this.renderCommonTemplate(null, container, 'list');
|
||||
|
||||
const listWidget = this._instantiationService.createInstance(ListSettingWidget, common.controlElement);
|
||||
listWidget.domNode.classList.add(AbstractSettingRenderer.CONTROL_CLASS);
|
||||
common.toDispose.push(listWidget);
|
||||
|
||||
const template: ISettingListItemTemplate = {
|
||||
...common,
|
||||
listWidget
|
||||
};
|
||||
|
||||
this.addSettingElementFocusHandler(template);
|
||||
|
||||
common.toDispose.push(listWidget.onDidChangeList(e => this.onDidChangeList(template, e)));
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
private onDidChangeList(template: ISettingListItemTemplate, e: IListChangeEvent): void {
|
||||
if (template.context) {
|
||||
const newValue: any[] | undefined = isArray(template.context.scopeValue)
|
||||
? [...template.context.scopeValue]
|
||||
: [...template.context.value];
|
||||
|
||||
// Delete value
|
||||
if (e.removeIndex) {
|
||||
if (!e.value && e.originalValue && e.removeIndex > -1) {
|
||||
newValue.splice(e.removeIndex, 1);
|
||||
}
|
||||
}
|
||||
// Add value
|
||||
else if (e.value && !e.originalValue) {
|
||||
newValue.push(e.value);
|
||||
}
|
||||
// Update value
|
||||
else if (e.value && e.originalValue) {
|
||||
const valueIndex = newValue.indexOf(e.originalValue);
|
||||
if (valueIndex > -1) {
|
||||
newValue[valueIndex] = e.value;
|
||||
}
|
||||
// For some reason, we are updating and cannot find original value
|
||||
// Just append the value in this case
|
||||
else {
|
||||
newValue.push(e.value);
|
||||
}
|
||||
}
|
||||
|
||||
this._onDidChangeSetting.fire({
|
||||
key: template.context.setting.key,
|
||||
value: newValue,
|
||||
type: template.context.valueType
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
renderElement(element: ITreeNode<SettingsTreeSettingElement, never>, index: number, templateData: ISettingListItemTemplate): void {
|
||||
super.renderSettingElement(element, index, templateData);
|
||||
}
|
||||
|
||||
protected renderValue(dataElement: SettingsTreeSettingElement, template: ISettingListItemTemplate, onChange: (value: string) => void): void {
|
||||
const value = getListDisplayValue(dataElement);
|
||||
template.listWidget.setValue(value);
|
||||
template.context = dataElement;
|
||||
}
|
||||
}
|
||||
|
||||
export class SettingExcludeRenderer extends AbstractSettingRenderer implements ITreeRenderer<SettingsTreeSettingElement, never, ISettingExcludeItemTemplate> {
|
||||
templateId = SETTINGS_EXCLUDE_TEMPLATE_ID;
|
||||
|
||||
renderTemplate(container: HTMLElement): ISettingExcludeItemTemplate {
|
||||
const common = this.renderCommonTemplate(null, container, 'exclude');
|
||||
const common = this.renderCommonTemplate(null, container, 'list');
|
||||
|
||||
const excludeWidget = this._instantiationService.createInstance(ExcludeSettingWidget, common.controlElement);
|
||||
excludeWidget.domNode.classList.add(AbstractSettingRenderer.CONTROL_CLASS);
|
||||
|
@ -673,32 +757,32 @@ export class SettingExcludeRenderer extends AbstractSettingRenderer implements I
|
|||
|
||||
this.addSettingElementFocusHandler(template);
|
||||
|
||||
common.toDispose.push(excludeWidget.onDidChangeExclude(e => this.onDidChangeExclude(template, e)));
|
||||
common.toDispose.push(excludeWidget.onDidChangeList(e => this.onDidChangeExclude(template, e)));
|
||||
|
||||
return template;
|
||||
}
|
||||
|
||||
private onDidChangeExclude(template: ISettingExcludeItemTemplate, e: IExcludeChangeEvent): void {
|
||||
private onDidChangeExclude(template: ISettingExcludeItemTemplate, e: IListChangeEvent): void {
|
||||
if (template.context) {
|
||||
const newValue = { ...template.context.scopeValue };
|
||||
|
||||
// first delete the existing entry, if present
|
||||
if (e.originalPattern) {
|
||||
if (e.originalPattern in template.context.defaultValue) {
|
||||
if (e.originalValue) {
|
||||
if (e.originalValue in template.context.defaultValue) {
|
||||
// delete a default by overriding it
|
||||
newValue[e.originalPattern] = false;
|
||||
newValue[e.originalValue] = false;
|
||||
} else {
|
||||
delete newValue[e.originalPattern];
|
||||
delete newValue[e.originalValue];
|
||||
}
|
||||
}
|
||||
|
||||
// then add the new or updated entry, if present
|
||||
if (e.pattern) {
|
||||
if (e.pattern in template.context.defaultValue && !e.sibling) {
|
||||
if (e.value) {
|
||||
if (e.value in template.context.defaultValue && !e.sibling) {
|
||||
// add a default by deleting its override
|
||||
delete newValue[e.pattern];
|
||||
delete newValue[e.value];
|
||||
} else {
|
||||
newValue[e.pattern] = e.sibling ? { when: e.sibling } : true;
|
||||
newValue[e.value] = e.sibling ? { when: e.sibling } : true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1056,6 +1140,7 @@ export class SettingTreeRenderers {
|
|||
this._instantiationService.createInstance(SettingBoolRenderer, this.settingActions),
|
||||
this._instantiationService.createInstance(SettingNumberRenderer, this.settingActions),
|
||||
this._instantiationService.createInstance(SettingBoolRenderer, this.settingActions),
|
||||
this._instantiationService.createInstance(SettingArrayRenderer, this.settingActions),
|
||||
this._instantiationService.createInstance(SettingComplexRenderer, this.settingActions),
|
||||
this._instantiationService.createInstance(SettingTextRenderer, this.settingActions),
|
||||
this._instantiationService.createInstance(SettingExcludeRenderer, this.settingActions),
|
||||
|
@ -1254,23 +1339,27 @@ class SettingsTreeDelegate implements IListVirtualDelegate<SettingsTreeGroupChil
|
|||
}
|
||||
|
||||
if (element instanceof SettingsTreeSettingElement) {
|
||||
if (element.valueType === 'boolean') {
|
||||
if (element.valueType === SettingValueType.Boolean) {
|
||||
return SETTINGS_BOOL_TEMPLATE_ID;
|
||||
}
|
||||
|
||||
if (element.valueType === 'integer' || element.valueType === 'number' || element.valueType === 'nullable-integer' || element.valueType === 'nullable-number') {
|
||||
if (element.valueType === SettingValueType.Integer || element.valueType === SettingValueType.Number || element.valueType === SettingValueType.NullableInteger || element.valueType === SettingValueType.NullableNumber) {
|
||||
return SETTINGS_NUMBER_TEMPLATE_ID;
|
||||
}
|
||||
|
||||
if (element.valueType === 'string') {
|
||||
if (element.valueType === SettingValueType.String) {
|
||||
return SETTINGS_TEXT_TEMPLATE_ID;
|
||||
}
|
||||
|
||||
if (element.valueType === 'enum') {
|
||||
if (element.valueType === SettingValueType.Enum) {
|
||||
return SETTINGS_ENUM_TEMPLATE_ID;
|
||||
}
|
||||
|
||||
if (element.valueType === 'exclude') {
|
||||
if (element.valueType === SettingValueType.ArrayOfString) {
|
||||
return SETTINGS_ARRAY_TEMPLATE_ID;
|
||||
}
|
||||
|
||||
if (element.valueType === SettingValueType.Exclude) {
|
||||
return SETTINGS_EXCLUDE_TEMPLATE_ID;
|
||||
}
|
||||
|
||||
|
|
|
@ -193,6 +193,8 @@ export class SettingsTreeSettingElement extends SettingsTreeElement {
|
|||
this.valueType = SettingValueType.Number;
|
||||
} else if (this.setting.type === 'boolean') {
|
||||
this.valueType = SettingValueType.Boolean;
|
||||
} else if (this.setting.type === 'array' && this.setting.arrayItemType === 'string') {
|
||||
this.valueType = SettingValueType.ArrayOfString;
|
||||
} 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;
|
||||
|
|
|
@ -87,35 +87,35 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
|||
collector.addRule(`.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label { color: ${foregroundColor}; }`);
|
||||
}
|
||||
|
||||
// Exclude control
|
||||
// List control
|
||||
const listHoverBackgroundColor = theme.getColor(listHoverBackground);
|
||||
if (listHoverBackgroundColor) {
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover { background-color: ${listHoverBackgroundColor}; }`);
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row:hover { background-color: ${listHoverBackgroundColor}; }`);
|
||||
}
|
||||
|
||||
const listHoverForegroundColor = theme.getColor(listHoverForeground);
|
||||
if (listHoverForegroundColor) {
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row:hover { color: ${listHoverForegroundColor}; }`);
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row:hover { color: ${listHoverForegroundColor}; }`);
|
||||
}
|
||||
|
||||
const listSelectBackgroundColor = theme.getColor(listActiveSelectionBackground);
|
||||
if (listSelectBackgroundColor) {
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:focus { background-color: ${listSelectBackgroundColor}; }`);
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row.selected:focus { background-color: ${listSelectBackgroundColor}; }`);
|
||||
}
|
||||
|
||||
const listInactiveSelectionBackgroundColor = theme.getColor(listInactiveSelectionBackground);
|
||||
if (listInactiveSelectionBackgroundColor) {
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:not(:focus) { background-color: ${listInactiveSelectionBackgroundColor}; }`);
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row.selected:not(:focus) { background-color: ${listInactiveSelectionBackgroundColor}; }`);
|
||||
}
|
||||
|
||||
const listInactiveSelectionForegroundColor = theme.getColor(listInactiveSelectionForeground);
|
||||
if (listInactiveSelectionForegroundColor) {
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:not(:focus) { color: ${listInactiveSelectionForegroundColor}; }`);
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row.selected:not(:focus) { color: ${listInactiveSelectionForegroundColor}; }`);
|
||||
}
|
||||
|
||||
const listSelectForegroundColor = theme.getColor(listActiveSelectionForeground);
|
||||
if (listSelectForegroundColor) {
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-exclude .setting-exclude-row.selected:focus { color: ${listSelectForegroundColor}; }`);
|
||||
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row.selected:focus { color: ${listSelectForegroundColor}; }`);
|
||||
}
|
||||
|
||||
const codeTextForegroundColor = theme.getColor(textPreformatForeground);
|
||||
|
@ -131,15 +131,15 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
|||
}
|
||||
});
|
||||
|
||||
export class ExcludeSettingListModel {
|
||||
private _dataItems: IExcludeDataItem[] = [];
|
||||
export class ListSettingListModel {
|
||||
private _dataItems: IListDataItem[] = [];
|
||||
private _editKey: string | null;
|
||||
private _selectedIdx: number | null;
|
||||
|
||||
get items(): IExcludeViewItem[] {
|
||||
get items(): IListViewItem[] {
|
||||
const items = this._dataItems.map((item, i) => {
|
||||
const editing = item.pattern === this._editKey;
|
||||
return <IExcludeViewItem>{
|
||||
const editing = item.value === this._editKey;
|
||||
return <IListViewItem>{
|
||||
...item,
|
||||
editing,
|
||||
selected: i === this._selectedIdx || editing
|
||||
|
@ -150,7 +150,7 @@ export class ExcludeSettingListModel {
|
|||
items.push({
|
||||
editing: true,
|
||||
selected: true,
|
||||
pattern: '',
|
||||
value: '',
|
||||
sibling: ''
|
||||
});
|
||||
}
|
||||
|
@ -162,8 +162,8 @@ export class ExcludeSettingListModel {
|
|||
this._editKey = key;
|
||||
}
|
||||
|
||||
setValue(excludeData: IExcludeDataItem[]): void {
|
||||
this._dataItems = excludeData;
|
||||
setValue(listData: IListDataItem[]): void {
|
||||
this._dataItems = listData;
|
||||
}
|
||||
|
||||
select(idx: number): void {
|
||||
|
@ -191,20 +191,21 @@ export class ExcludeSettingListModel {
|
|||
}
|
||||
}
|
||||
|
||||
export interface IExcludeChangeEvent {
|
||||
originalPattern: string;
|
||||
pattern?: string;
|
||||
export interface IListChangeEvent {
|
||||
originalValue: string;
|
||||
value?: string;
|
||||
sibling?: string;
|
||||
removeIndex?: number;
|
||||
}
|
||||
|
||||
export class ExcludeSettingWidget extends Disposable {
|
||||
export class ListSettingWidget extends Disposable {
|
||||
private listElement: HTMLElement;
|
||||
private readonly listDisposables = this._register(new DisposableStore());
|
||||
|
||||
private model = new ExcludeSettingListModel();
|
||||
private model = new ListSettingListModel();
|
||||
|
||||
private readonly _onDidChangeExclude = this._register(new Emitter<IExcludeChangeEvent>());
|
||||
readonly onDidChangeExclude: Event<IExcludeChangeEvent> = this._onDidChangeExclude.event;
|
||||
private readonly _onDidChangeList = this._register(new Emitter<IListChangeEvent>());
|
||||
readonly onDidChangeList: Event<IListChangeEvent> = this._onDidChangeList.event;
|
||||
|
||||
get domNode(): HTMLElement {
|
||||
return this.listElement;
|
||||
|
@ -217,7 +218,7 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
) {
|
||||
super();
|
||||
|
||||
this.listElement = DOM.append(container, $('.setting-exclude-widget'));
|
||||
this.listElement = DOM.append(container, $('.setting-list-widget'));
|
||||
this.listElement.setAttribute('tabindex', '0');
|
||||
DOM.append(container, this.renderAddButton());
|
||||
this.renderList();
|
||||
|
@ -240,8 +241,26 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
}));
|
||||
}
|
||||
|
||||
setValue(excludeData: IExcludeDataItem[]): void {
|
||||
this.model.setValue(excludeData);
|
||||
protected getLocalizedStrings() {
|
||||
return {
|
||||
deleteActionTooltip: localize('removeItem', "Remove Item"),
|
||||
editActionTooltip: localize('editItem', "Edit Item"),
|
||||
complexEditActionTooltip: localize('editItemInSettingsJson', "Edit Item in settings.json"),
|
||||
addButtonLabel: localize('addItem', "Add Item"),
|
||||
inputPlaceholder: localize('itemInputPlaceholder', "String Item..."),
|
||||
siblingInputPlaceholder: localize('listSiblingInputPlaceholder', "Sibling...")
|
||||
};
|
||||
}
|
||||
|
||||
protected getSettingListRowLocalizedStrings(value?: string, sibling?: string) {
|
||||
return {
|
||||
settingListRowValueHintLabel: localize('listValueHintLabel', "List item `{0}`", value),
|
||||
settingListRowSiblingHintLabel: localize('listSiblingHintLabel', "List item `{0}` with sibling `${1}`", value)
|
||||
};
|
||||
}
|
||||
|
||||
setValue(listData: IListDataItem[]): void {
|
||||
this.model.setValue(listData);
|
||||
this.renderList();
|
||||
}
|
||||
|
||||
|
@ -269,7 +288,7 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
|
||||
const item = this.model.items[targetIdx];
|
||||
if (item) {
|
||||
this.editSetting(item.pattern);
|
||||
this.editSetting(item.value);
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
@ -286,7 +305,7 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
return -1;
|
||||
}
|
||||
|
||||
const element = DOM.findParentWithClass((<any>e.target), 'setting-exclude-row');
|
||||
const element = DOM.findParentWithClass((<any>e.target), 'setting-list-row');
|
||||
if (!element) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -306,8 +325,8 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
DOM.clearNode(this.listElement);
|
||||
this.listDisposables.clear();
|
||||
|
||||
const newMode = this.model.items.some(item => !!(item.editing && !item.pattern));
|
||||
DOM.toggleClass(this.container, 'setting-exclude-new-mode', newMode);
|
||||
const newMode = this.model.items.some(item => !!(item.editing && !item.value));
|
||||
DOM.toggleClass(this.container, 'setting-list-new-mode', newMode);
|
||||
|
||||
this.model.items
|
||||
.map((item, i) => this.renderItem(item, i, focused))
|
||||
|
@ -317,22 +336,22 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
this.listElement.style.height = listHeight + 'px';
|
||||
}
|
||||
|
||||
private createDeleteAction(key: string): IAction {
|
||||
private createDeleteAction(key: string, idx: number): IAction {
|
||||
return <IAction>{
|
||||
class: 'setting-excludeAction-remove',
|
||||
class: 'setting-listAction-remove',
|
||||
enabled: true,
|
||||
id: 'workbench.action.removeExcludeItem',
|
||||
tooltip: localize('removeExcludeItem', "Remove Exclude Item"),
|
||||
run: () => this._onDidChangeExclude.fire({ originalPattern: key, pattern: undefined })
|
||||
id: 'workbench.action.removeListItem',
|
||||
tooltip: this.getLocalizedStrings().deleteActionTooltip,
|
||||
run: () => this._onDidChangeList.fire({ originalValue: key, value: undefined, removeIndex: idx })
|
||||
};
|
||||
}
|
||||
|
||||
private createEditAction(key: string): IAction {
|
||||
return <IAction>{
|
||||
class: 'setting-excludeAction-edit',
|
||||
class: 'setting-listAction-edit',
|
||||
enabled: true,
|
||||
id: 'workbench.action.editExcludeItem',
|
||||
tooltip: localize('editExcludeItem', "Edit Exclude Item"),
|
||||
id: 'workbench.action.editListItem',
|
||||
tooltip: this.getLocalizedStrings().editActionTooltip,
|
||||
run: () => {
|
||||
this.editSetting(key);
|
||||
}
|
||||
|
@ -344,14 +363,14 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
this.renderList();
|
||||
}
|
||||
|
||||
private renderItem(item: IExcludeViewItem, idx: number, listFocused: boolean): HTMLElement {
|
||||
private renderItem(item: IListViewItem, idx: number, listFocused: boolean): HTMLElement {
|
||||
return item.editing ?
|
||||
this.renderEditItem(item) :
|
||||
this.renderDataItem(item, idx, listFocused);
|
||||
}
|
||||
|
||||
private renderDataItem(item: IExcludeViewItem, idx: number, listFocused: boolean): HTMLElement {
|
||||
const rowElement = $('.setting-exclude-row');
|
||||
private renderDataItem(item: IListViewItem, idx: number, listFocused: boolean): HTMLElement {
|
||||
const rowElement = $('.setting-list-row');
|
||||
rowElement.setAttribute('data-index', idx + '');
|
||||
rowElement.setAttribute('tabindex', item.selected ? '0' : '-1');
|
||||
DOM.toggleClass(rowElement, 'selected', item.selected);
|
||||
|
@ -359,19 +378,19 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
const actionBar = new ActionBar(rowElement);
|
||||
this.listDisposables.add(actionBar);
|
||||
|
||||
const patternElement = DOM.append(rowElement, $('.setting-exclude-pattern'));
|
||||
const siblingElement = DOM.append(rowElement, $('.setting-exclude-sibling'));
|
||||
patternElement.textContent = item.pattern;
|
||||
const valueElement = DOM.append(rowElement, $('.setting-list-value'));
|
||||
const siblingElement = DOM.append(rowElement, $('.setting-list-sibling'));
|
||||
valueElement.textContent = item.value;
|
||||
siblingElement.textContent = item.sibling ? ('when: ' + item.sibling) : null;
|
||||
|
||||
actionBar.push([
|
||||
this.createEditAction(item.pattern),
|
||||
this.createDeleteAction(item.pattern)
|
||||
this.createEditAction(item.value),
|
||||
this.createDeleteAction(item.value, idx)
|
||||
], { icon: true, label: false });
|
||||
|
||||
rowElement.title = item.sibling ?
|
||||
localize('excludeSiblingHintLabel', "Exclude files matching `{0}`, only when a file matching `{1}` is present", item.pattern, item.sibling) :
|
||||
localize('excludePatternHintLabel', "Exclude files matching `{0}`", item.pattern);
|
||||
rowElement.title = item.sibling
|
||||
? this.getSettingListRowLocalizedStrings(item.value, item.sibling).settingListRowSiblingHintLabel
|
||||
: this.getSettingListRowLocalizedStrings(item.value, item.sibling).settingListRowValueHintLabel;
|
||||
|
||||
if (item.selected) {
|
||||
if (listFocused) {
|
||||
|
@ -385,11 +404,11 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
}
|
||||
|
||||
private renderAddButton(): HTMLElement {
|
||||
const rowElement = $('.setting-exclude-new-row');
|
||||
const rowElement = $('.setting-list-new-row');
|
||||
|
||||
const startAddButton = this._register(new Button(rowElement));
|
||||
startAddButton.label = localize('addPattern', "Add Pattern");
|
||||
startAddButton.element.classList.add('setting-exclude-addButton');
|
||||
startAddButton.label = this.getLocalizedStrings().addButtonLabel;
|
||||
startAddButton.element.classList.add('setting-list-addButton');
|
||||
this._register(attachButtonStyler(startAddButton, this.themeService));
|
||||
|
||||
this._register(startAddButton.onDidClick(() => {
|
||||
|
@ -400,16 +419,16 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
return rowElement;
|
||||
}
|
||||
|
||||
private renderEditItem(item: IExcludeViewItem): HTMLElement {
|
||||
const rowElement = $('.setting-exclude-edit-row');
|
||||
private renderEditItem(item: IListViewItem): HTMLElement {
|
||||
const rowElement = $('.setting-list-edit-row');
|
||||
|
||||
const onSubmit = (edited: boolean) => {
|
||||
this.model.setEditKey(null);
|
||||
const pattern = patternInput.value.trim();
|
||||
if (edited && pattern) {
|
||||
this._onDidChangeExclude.fire({
|
||||
originalPattern: item.pattern,
|
||||
pattern,
|
||||
const value = valueInput.value.trim();
|
||||
if (edited && value) {
|
||||
this._onDidChangeList.fire({
|
||||
originalValue: item.value,
|
||||
value: value,
|
||||
sibling: siblingInput && siblingInput.value.trim()
|
||||
});
|
||||
}
|
||||
|
@ -425,25 +444,26 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
}
|
||||
};
|
||||
|
||||
const patternInput = new InputBox(rowElement, this.contextViewService, {
|
||||
placeholder: localize('excludePatternInputPlaceholder', "Exclude Pattern...")
|
||||
const valueInput = new InputBox(rowElement, this.contextViewService, {
|
||||
placeholder: this.getLocalizedStrings().inputPlaceholder
|
||||
});
|
||||
patternInput.element.classList.add('setting-exclude-patternInput');
|
||||
this.listDisposables.add(attachInputBoxStyler(patternInput, this.themeService, {
|
||||
|
||||
valueInput.element.classList.add('setting-list-valueInput');
|
||||
this.listDisposables.add(attachInputBoxStyler(valueInput, this.themeService, {
|
||||
inputBackground: settingsTextInputBackground,
|
||||
inputForeground: settingsTextInputForeground,
|
||||
inputBorder: settingsTextInputBorder
|
||||
}));
|
||||
this.listDisposables.add(patternInput);
|
||||
patternInput.value = item.pattern;
|
||||
this.listDisposables.add(DOM.addStandardDisposableListener(patternInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown));
|
||||
this.listDisposables.add(valueInput);
|
||||
valueInput.value = item.value;
|
||||
this.listDisposables.add(DOM.addStandardDisposableListener(valueInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown));
|
||||
|
||||
let siblingInput: InputBox;
|
||||
if (item.sibling) {
|
||||
siblingInput = new InputBox(rowElement, this.contextViewService, {
|
||||
placeholder: localize('excludeSiblingInputPlaceholder', "When Pattern Is Present...")
|
||||
placeholder: this.getLocalizedStrings().siblingInputPlaceholder
|
||||
});
|
||||
siblingInput.element.classList.add('setting-exclude-siblingInput');
|
||||
siblingInput.element.classList.add('setting-list-siblingInput');
|
||||
this.listDisposables.add(siblingInput);
|
||||
this.listDisposables.add(attachInputBoxStyler(siblingInput, this.themeService, {
|
||||
inputBackground: settingsTextInputBackground,
|
||||
|
@ -456,32 +476,52 @@ export class ExcludeSettingWidget extends Disposable {
|
|||
|
||||
const okButton = this._register(new Button(rowElement));
|
||||
okButton.label = localize('okButton', "OK");
|
||||
okButton.element.classList.add('setting-exclude-okButton');
|
||||
okButton.element.classList.add('setting-list-okButton');
|
||||
this.listDisposables.add(attachButtonStyler(okButton, this.themeService));
|
||||
this.listDisposables.add(okButton.onDidClick(() => onSubmit(true)));
|
||||
|
||||
const cancelButton = this._register(new Button(rowElement));
|
||||
cancelButton.label = localize('cancelButton', "Cancel");
|
||||
cancelButton.element.classList.add('setting-exclude-cancelButton');
|
||||
cancelButton.element.classList.add('setting-list-okButton');
|
||||
this.listDisposables.add(attachButtonStyler(cancelButton, this.themeService));
|
||||
this.listDisposables.add(cancelButton.onDidClick(() => onSubmit(false)));
|
||||
|
||||
this.listDisposables.add(
|
||||
disposableTimeout(() => {
|
||||
patternInput.focus();
|
||||
patternInput.select();
|
||||
valueInput.focus();
|
||||
valueInput.select();
|
||||
}));
|
||||
|
||||
return rowElement;
|
||||
}
|
||||
}
|
||||
|
||||
export interface IExcludeDataItem {
|
||||
pattern: string;
|
||||
export class ExcludeSettingWidget extends ListSettingWidget {
|
||||
protected getLocalizedStrings() {
|
||||
return {
|
||||
deleteActionTooltip: localize('removeExcludeItem', "Remove Exclude Item"),
|
||||
editActionTooltip: localize('editExcludeItem', "Edit Exclude Item"),
|
||||
complexEditActionTooltip: localize('editExcludeItemInSettingsJson', "Edit Exclude Item in settings.json"),
|
||||
addButtonLabel: localize('addPattern', "Add Pattern"),
|
||||
inputPlaceholder: localize('excludePatternInputPlaceholder', "Exclude Pattern..."),
|
||||
siblingInputPlaceholder: localize('excludeSiblingInputPlaceholder', "When Pattern Is Present...")
|
||||
};
|
||||
}
|
||||
|
||||
protected getSettingListRowLocalizedStrings(pattern?: string, sibling?: string) {
|
||||
return {
|
||||
settingListRowValueHintLabel: localize('excludePatternHintLabel', "Exclude files matching `{0}`", pattern),
|
||||
settingListRowSiblingHintLabel: localize('excludeSiblingHintLabel', "Exclude files matching `{0}`, only when a file matching `{1}` is present", pattern, sibling)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface IListDataItem {
|
||||
value: string;
|
||||
sibling?: string;
|
||||
}
|
||||
|
||||
interface IExcludeViewItem extends IExcludeDataItem {
|
||||
interface IListViewItem extends IListDataItem {
|
||||
editing?: boolean;
|
||||
selected?: boolean;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ export enum SettingValueType {
|
|||
Integer = 'integer',
|
||||
Number = 'number',
|
||||
Boolean = 'boolean',
|
||||
ArrayOfString = 'array-of-string',
|
||||
Exclude = 'exclude',
|
||||
Complex = 'complex',
|
||||
NullableInteger = 'nullable-integer',
|
||||
|
@ -61,6 +62,7 @@ export interface ISetting {
|
|||
|
||||
scope?: ConfigurationScope;
|
||||
type?: string | string[];
|
||||
arrayItemType?: string;
|
||||
enum?: string[];
|
||||
enumDescriptions?: string[];
|
||||
enumDescriptionsAreMarkdown?: boolean;
|
||||
|
|
|
@ -22,7 +22,7 @@ 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 { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { withNullAsUndefined, isArray } from 'vs/base/common/types';
|
||||
|
||||
export const nullRange: IRange = { startLineNumber: -1, startColumn: -1, endLineNumber: -1, endColumn: -1 };
|
||||
export function isNullRange(range: IRange): boolean { return range.startLineNumber === -1 && range.startColumn === -1 && range.endLineNumber === -1 && range.endColumn === -1; }
|
||||
|
@ -613,6 +613,10 @@ export class DefaultSettings extends Disposable {
|
|||
const value = prop.default;
|
||||
const description = (prop.description || prop.markdownDescription || '').split('\n');
|
||||
const overrides = OVERRIDE_PROPERTY_PATTERN.test(key) ? this.parseOverrideSettings(prop.default) : [];
|
||||
const listItemType = prop.type === 'array' && prop.items && !isArray(prop.items) && prop.items.type && !isArray(prop.items.type)
|
||||
? prop.items.type
|
||||
: undefined;
|
||||
|
||||
result.push({
|
||||
key,
|
||||
value,
|
||||
|
@ -625,6 +629,7 @@ export class DefaultSettings extends Disposable {
|
|||
overrides,
|
||||
scope: prop.scope,
|
||||
type: prop.type,
|
||||
arrayItemType: listItemType,
|
||||
enum: prop.enum,
|
||||
enumDescriptions: prop.enumDescriptions || prop.markdownEnumDescriptions,
|
||||
enumDescriptionsAreMarkdown: !prop.enumDescriptions,
|
||||
|
|
Loading…
Reference in a new issue