|
|
|
|
@@ -3,16 +3,17 @@
|
|
|
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
|
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
import { BrowserFeatures } from 'vs/base/browser/canIUse';
|
|
|
|
|
import * as DOM from 'vs/base/browser/dom';
|
|
|
|
|
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
|
|
|
|
|
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
|
|
|
|
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
|
|
|
|
|
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
|
|
|
|
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
|
|
|
|
import { alert as ariaAlert } from 'vs/base/browser/ui/aria/aria';
|
|
|
|
|
import { Button } from 'vs/base/browser/ui/button/button';
|
|
|
|
|
import { Checkbox } from 'vs/base/browser/ui/checkbox/checkbox';
|
|
|
|
|
import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox';
|
|
|
|
|
import { ListAriaRootRole, CachedListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
|
|
|
|
import { CachedListVirtualDelegate, ListAriaRootRole } from 'vs/base/browser/ui/list/list';
|
|
|
|
|
import { DefaultStyleController } from 'vs/base/browser/ui/list/listWidget';
|
|
|
|
|
import { ISelectOptionItem, SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
|
|
|
|
|
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
|
|
|
|
|
@@ -25,29 +26,29 @@ import { Color, RGBA } from 'vs/base/common/color';
|
|
|
|
|
import { onUnexpectedError } from 'vs/base/common/errors';
|
|
|
|
|
import { Emitter, Event } from 'vs/base/common/event';
|
|
|
|
|
import { KeyCode } from 'vs/base/common/keyCodes';
|
|
|
|
|
import { dispose, IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
|
|
|
|
import { Disposable, DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
|
|
|
|
import { isIOS } from 'vs/base/common/platform';
|
|
|
|
|
import { ISpliceable } from 'vs/base/common/sequence';
|
|
|
|
|
import { escapeRegExpCharacters, startsWith } from 'vs/base/common/strings';
|
|
|
|
|
import { isArray } from 'vs/base/common/types';
|
|
|
|
|
import { localize } from 'vs/nls';
|
|
|
|
|
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
|
|
|
|
import { ICommandService } from 'vs/platform/commands/common/commands';
|
|
|
|
|
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
|
|
|
|
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
|
|
|
|
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
|
|
|
|
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
|
|
|
|
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
|
|
|
|
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
|
|
|
|
import { errorForeground, focusBorder, foreground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground, editorBackground } from 'vs/platform/theme/common/colorRegistry';
|
|
|
|
|
import { editorBackground, errorForeground, focusBorder, foreground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground } from 'vs/platform/theme/common/colorRegistry';
|
|
|
|
|
import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler';
|
|
|
|
|
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
|
|
|
|
import { getIgnoredSettings } from 'vs/platform/userDataSync/common/settingsSync';
|
|
|
|
|
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 { ListSettingWidget, IListChangeEvent, IListDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, ExcludeSettingWidget } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
|
|
|
|
|
import { ExcludeSettingWidget, IListChangeEvent, IListDataItem, ListSettingWidget, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } 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';
|
|
|
|
|
import { BrowserFeatures } from 'vs/base/browser/canIUse';
|
|
|
|
|
import { isIOS } from 'vs/base/common/platform';
|
|
|
|
|
import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
|
|
|
|
|
|
|
|
|
|
const $ = DOM.$;
|
|
|
|
|
|
|
|
|
|
@@ -203,6 +204,7 @@ interface ISettingItemTemplate<T = any> extends IDisposableTemplate {
|
|
|
|
|
deprecationWarningElement: HTMLElement;
|
|
|
|
|
otherOverridesElement: HTMLElement;
|
|
|
|
|
toolbar: ToolBar;
|
|
|
|
|
elementDisposables: IDisposable[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface ISettingBoolItemTemplate extends ISettingItemTemplate<boolean> {
|
|
|
|
|
@@ -300,6 +302,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
|
|
|
|
|
// Put common injections back here
|
|
|
|
|
constructor(
|
|
|
|
|
private readonly settingActions: IAction[],
|
|
|
|
|
private readonly disposableActionFactory: (setting: ISetting) => IAction[],
|
|
|
|
|
@IThemeService protected readonly _themeService: IThemeService,
|
|
|
|
|
@IContextViewService protected readonly _contextViewService: IContextViewService,
|
|
|
|
|
@IOpenerService protected readonly _openerService: IOpenerService,
|
|
|
|
|
@@ -345,6 +348,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
|
|
|
|
|
|
|
|
|
|
const template: ISettingItemTemplate = {
|
|
|
|
|
toDispose,
|
|
|
|
|
elementDisposables: [],
|
|
|
|
|
|
|
|
|
|
containerElement: container,
|
|
|
|
|
categoryElement,
|
|
|
|
|
@@ -393,23 +397,27 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
|
|
|
|
|
const toolbar = new ToolBar(container, this._contextMenuService, {
|
|
|
|
|
toggleMenuTitle
|
|
|
|
|
});
|
|
|
|
|
toolbar.setActions([], this.settingActions)();
|
|
|
|
|
return toolbar;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const button = container.querySelector('.codicon-more');
|
|
|
|
|
private fixToolbarIcon(toolbar: ToolBar): void {
|
|
|
|
|
const button = toolbar.getContainer().querySelector('.codicon-more');
|
|
|
|
|
if (button) {
|
|
|
|
|
(<HTMLElement>button).tabIndex = -1;
|
|
|
|
|
|
|
|
|
|
// change icon from ellipsis to gear
|
|
|
|
|
(<HTMLElement>button).classList.add('codicon-gear');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return toolbar;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected renderSettingElement(node: ITreeNode<SettingsTreeSettingElement, never>, index: number, template: ISettingItemTemplate | ISettingBoolItemTemplate): void {
|
|
|
|
|
const element = node.element;
|
|
|
|
|
template.context = element;
|
|
|
|
|
template.toolbar.context = element;
|
|
|
|
|
const actions = this.disposableActionFactory(element.setting);
|
|
|
|
|
template.elementDisposables?.push(...actions);
|
|
|
|
|
template.toolbar.setActions([], [...this.settingActions, ...actions])();
|
|
|
|
|
this.fixToolbarIcon(template.toolbar);
|
|
|
|
|
|
|
|
|
|
const setting = element.setting;
|
|
|
|
|
|
|
|
|
|
@@ -455,14 +463,15 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
|
|
|
|
|
DOM.append(template.otherOverridesElement, $('span', undefined, ')'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DOM.addStandardDisposableListener(view, DOM.EventType.CLICK, (e: IMouseEvent) => {
|
|
|
|
|
this._onDidClickOverrideElement.fire({
|
|
|
|
|
targetKey: element.setting.key,
|
|
|
|
|
scope: element.overriddenScopeList[i]
|
|
|
|
|
});
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
});
|
|
|
|
|
template.elementDisposables.push(
|
|
|
|
|
DOM.addStandardDisposableListener(view, DOM.EventType.CLICK, (e: IMouseEvent) => {
|
|
|
|
|
this._onDidClickOverrideElement.fire({
|
|
|
|
|
targetKey: element.setting.key,
|
|
|
|
|
scope: element.overriddenScopeList[i]
|
|
|
|
|
});
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -472,7 +481,6 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
|
|
|
|
|
DOM.toggleClass(template.containerElement, 'is-deprecated', !!deprecationText);
|
|
|
|
|
|
|
|
|
|
this.renderValue(element, <ISettingItemTemplate>template, onChange);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private renderDescriptionMarkdown(element: SettingsTreeSettingElement, text: string, disposeables: DisposableStore): HTMLElement {
|
|
|
|
|
@@ -563,6 +571,12 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
|
|
|
|
|
disposeTemplate(template: IDisposableTemplate): void {
|
|
|
|
|
dispose(template.toDispose);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
disposeElement(_element: ITreeNode<SettingsTreeElement>, _index: number, template: IDisposableTemplate, _height: number | undefined): void {
|
|
|
|
|
if ((template as ISettingItemTemplate).elementDisposables) {
|
|
|
|
|
dispose((template as ISettingItemTemplate).elementDisposables);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class SettingGroupRenderer implements ITreeRenderer<SettingsTreeGroupElement, never, IGroupTitleTemplate> {
|
|
|
|
|
@@ -1113,6 +1127,7 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
|
|
|
|
|
|
|
|
|
|
const template: ISettingBoolItemTemplate = {
|
|
|
|
|
toDispose: [toDispose],
|
|
|
|
|
elementDisposables: [],
|
|
|
|
|
|
|
|
|
|
containerElement: container,
|
|
|
|
|
categoryElement,
|
|
|
|
|
@@ -1190,15 +1205,16 @@ export class SettingTreeRenderers {
|
|
|
|
|
this._instantiationService.createInstance(CopySettingAsJSONAction),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const actionFactory = (setting: ISetting) => [this._instantiationService.createInstance(StopSyncingSettingAction, setting)];
|
|
|
|
|
const settingRenderers = [
|
|
|
|
|
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),
|
|
|
|
|
this._instantiationService.createInstance(SettingEnumRenderer, this.settingActions),
|
|
|
|
|
this._instantiationService.createInstance(SettingBoolRenderer, this.settingActions, actionFactory),
|
|
|
|
|
this._instantiationService.createInstance(SettingNumberRenderer, this.settingActions, actionFactory),
|
|
|
|
|
this._instantiationService.createInstance(SettingBoolRenderer, this.settingActions, actionFactory),
|
|
|
|
|
this._instantiationService.createInstance(SettingArrayRenderer, this.settingActions, actionFactory),
|
|
|
|
|
this._instantiationService.createInstance(SettingComplexRenderer, this.settingActions, actionFactory),
|
|
|
|
|
this._instantiationService.createInstance(SettingTextRenderer, this.settingActions, actionFactory),
|
|
|
|
|
this._instantiationService.createInstance(SettingExcludeRenderer, this.settingActions, actionFactory),
|
|
|
|
|
this._instantiationService.createInstance(SettingEnumRenderer, this.settingActions, actionFactory),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
this.onDidClickOverrideElement = Event.any(...settingRenderers.map(r => r.onDidClickOverrideElement));
|
|
|
|
|
@@ -1596,3 +1612,32 @@ class CopySettingAsJSONAction extends Action {
|
|
|
|
|
return Promise.resolve(undefined);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class StopSyncingSettingAction extends Action {
|
|
|
|
|
static readonly ID = 'settings.stopSyncingSetting';
|
|
|
|
|
static readonly LABEL = localize('stopSyncingSetting', "Don't Sync This Setting");
|
|
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
|
private readonly setting: ISetting,
|
|
|
|
|
@IConfigurationService private readonly configService: IConfigurationService,
|
|
|
|
|
) {
|
|
|
|
|
super(StopSyncingSettingAction.ID, StopSyncingSettingAction.LABEL);
|
|
|
|
|
this.update();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update() {
|
|
|
|
|
const ignoredSettings = getIgnoredSettings(this.configService);
|
|
|
|
|
this.checked = ignoredSettings.includes(this.setting.key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async run(): Promise<void> {
|
|
|
|
|
const currentValue = this.configService.getValue<string[]>('sync.ignoredSettings');
|
|
|
|
|
if (this.checked) {
|
|
|
|
|
this.configService.updateValue('sync.ignoredSettings', currentValue.filter(v => v !== this.setting.key));
|
|
|
|
|
} else {
|
|
|
|
|
this.configService.updateValue('sync.ignoredSettings', [...currentValue, this.setting.key]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return Promise.resolve(undefined);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|