Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -20,7 +20,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition } from 'vs/editor/browser/editorBrowser';
import { attachInputBoxStyler, attachStylerCallback } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { editorWidgetBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
import { editorWidgetBackground, editorWidgetForeground, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
import { ScrollType } from 'vs/editor/common/editorCommon';
import { SearchWidget, SearchOptions } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets';
import { withNullAsUndefined } from 'vs/base/common/types';
@@ -227,12 +227,17 @@ export class DefineKeybindingWidget extends Widget {
const message = nls.localize('defineKeybinding.initial', "Press desired key combination and then press ENTER.");
dom.append(this._domNode.domNode, dom.$('.message', undefined, message));
this._register(attachStylerCallback(this.themeService, { editorWidgetBackground, widgetShadow }, colors => {
this._register(attachStylerCallback(this.themeService, { editorWidgetBackground, editorWidgetForeground, widgetShadow }, colors => {
if (colors.editorWidgetBackground) {
this._domNode.domNode.style.backgroundColor = colors.editorWidgetBackground.toString();
} else {
this._domNode.domNode.style.backgroundColor = null;
}
if (colors.editorWidgetForeground) {
this._domNode.domNode.style.color = colors.editorWidgetForeground.toString();
} else {
this._domNode.domNode.style.color = null;
}
if (colors.widgetShadow) {
this._domNode.domNode.style.boxShadow = `0 2px 8px ${colors.widgetShadow}`;

View File

@@ -8,7 +8,7 @@ import { localize } from 'vs/nls';
import { Delayer } from 'vs/base/common/async';
import * as DOM from 'vs/base/browser/dom';
import { OS } from 'vs/base/common/platform';
import { dispose, Disposable, toDisposable, IDisposable } from 'vs/base/common/lifecycle';
import { dispose, Disposable, IDisposable, combinedDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { CheckboxActionViewItem } from 'vs/base/browser/ui/checkbox/checkbox';
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel';
@@ -248,7 +248,7 @@ export class KeybindingsEditor extends BaseEditor implements IKeybindingsEditor
});
}
copyKeybinding(keybinding: IKeybindingItemEntry): void {
async copyKeybinding(keybinding: IKeybindingItemEntry): Promise<void> {
this.selectEntry(keybinding);
this.reportKeybindingAction(KEYBINDINGS_EDITOR_COMMAND_COPY, keybinding.keybindingItem.command, keybinding.keybindingItem.keybinding);
const userFriendlyKeybinding: IUserFriendlyKeybinding = {
@@ -258,13 +258,13 @@ export class KeybindingsEditor extends BaseEditor implements IKeybindingsEditor
if (keybinding.keybindingItem.when) {
userFriendlyKeybinding.when = keybinding.keybindingItem.when;
}
this.clipboardService.writeText(JSON.stringify(userFriendlyKeybinding, null, ' '));
await this.clipboardService.writeText(JSON.stringify(userFriendlyKeybinding, null, ' '));
}
copyKeybindingCommand(keybinding: IKeybindingItemEntry): void {
async copyKeybindingCommand(keybinding: IKeybindingItemEntry): Promise<void> {
this.selectEntry(keybinding);
this.reportKeybindingAction(KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, keybinding.keybindingItem.command, keybinding.keybindingItem.keybinding);
this.clipboardService.writeText(keybinding.keybindingItem.command);
await this.clipboardService.writeText(keybinding.keybindingItem.command);
}
focusSearch(): void {
@@ -490,10 +490,10 @@ export class KeybindingsEditor extends BaseEditor implements IKeybindingsEditor
if (this.input) {
const input: KeybindingsEditorInput = this.input as KeybindingsEditorInput;
this.keybindingsEditorModel = await input.resolve();
const editorActionsLabels: { [id: string]: string; } = EditorExtensionsRegistry.getEditorActions().reduce((editorActions, editorAction) => {
editorActions[editorAction.id] = editorAction.label;
const editorActionsLabels: Map<string, string> = EditorExtensionsRegistry.getEditorActions().reduce((editorActions, editorAction) => {
editorActions.set(editorAction.id, editorAction.label);
return editorActions;
}, {});
}, new Map<string, string>());
await this.keybindingsEditorModel.resolve(editorActionsLabels);
this.renderKeybindingsEntries(false, preserveFocus);
if (input.searchOptions) {
@@ -804,7 +804,7 @@ class KeybindingItemRenderer implements IListRenderer<IKeybindingItemEntry, Keyb
const source = this.instantiationService.createInstance(SourceColumn, parent, this.keybindingsEditor);
const columns: Column[] = [actions, command, keybinding, when, source];
const disposables: IDisposable[] = [...columns];
const disposables = combinedDisposable(...columns);
const elements = columns.map(({ element }) => element);
this.keybindingsEditor.layoutColumns(elements);
@@ -814,7 +814,7 @@ class KeybindingItemRenderer implements IListRenderer<IKeybindingItemEntry, Keyb
return {
parent,
columns,
disposable: toDisposable(() => dispose(disposables))
disposable: disposables
};
}
@@ -897,6 +897,7 @@ class ActionsColumn extends Column {
}
dispose(): void {
super.dispose();
dispose(this.actionBar);
}
}
@@ -1015,7 +1016,7 @@ class WhenColumn extends Column {
readonly element: HTMLElement;
private whenLabel: HTMLElement;
private whenInput: InputBox;
private disposables: IDisposable[] = [];
private readonly renderDisposables = this._register(new DisposableStore());
private _onDidAccept: Emitter<void> = this._register(new Emitter<void>());
private readonly onDidAccept: Event<void> = this._onDidAccept.event;
@@ -1031,7 +1032,6 @@ class WhenColumn extends Column {
) {
super(keybindingsEditor);
this.element = this.create(parent);
this._register(toDisposable(() => this.disposables = dispose(this.disposables)));
}
private create(parent: HTMLElement): HTMLElement {
@@ -1094,14 +1094,14 @@ class WhenColumn extends Column {
}
render(keybindingItemEntry: IKeybindingItemEntry): void {
this.disposables = dispose(this.disposables);
this.renderDisposables.clear();
DOM.clearNode(this.whenLabel);
this.keybindingsEditor.onDefineWhenExpression(e => {
if (keybindingItemEntry === e) {
this.startEditing();
}
}, this, this.disposables);
}, this, this.renderDisposables);
this.whenInput.value = keybindingItemEntry.keybindingItem.when || '';
this.whenLabel.setAttribute('aria-label', this.getAriaLabel(keybindingItemEntry));
DOM.toggleClass(this.whenLabel, 'code', !!keybindingItemEntry.keybindingItem.when);
@@ -1118,11 +1118,11 @@ class WhenColumn extends Column {
this.onDidAccept(() => {
this.keybindingsEditor.updateKeybinding(keybindingItemEntry, keybindingItemEntry.keybindingItem.keybinding ? keybindingItemEntry.keybindingItem.keybinding.getUserSettingsLabel() || '' : '', this.whenInput.value);
this.keybindingsEditor.selectKeybinding(keybindingItemEntry);
}, this, this.disposables);
}, this, this.renderDisposables);
this.onDidReject(() => {
this.whenInput.value = keybindingItemEntry.keybindingItem.when || '';
this.keybindingsEditor.selectKeybinding(keybindingItemEntry);
}, this, this.disposables);
}, this, this.renderDisposables);
}
private getAriaLabel(keybindingItemEntry: IKeybindingItemEntry): string {

View File

@@ -23,11 +23,13 @@ import { parseTree, Node } from 'vs/base/common/json';
import { ScanCodeBinding } from 'vs/base/common/scanCode';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
import { WindowsNativeResolvedKeybinding } from 'vs/workbench/services/keybinding/common/windowsKeyboardMapper';
import { themeColorFromId, ThemeColor } from 'vs/platform/theme/common/themeService';
import { themeColorFromId, ThemeColor, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { overviewRulerInfo, overviewRulerError } from 'vs/editor/common/view/editorColorRegistry';
import { IModelDeltaDecoration, ITextModel, TrackedRangeStickiness, OverviewRulerLane } from 'vs/editor/common/model';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { KeybindingParser } from 'vs/base/common/keybindingParser';
import Severity from 'vs/base/common/severity';
import { SeverityIcon } from 'vs/platform/severityIcon/common/severityIcon';
const NLS_LAUNCH_MESSAGE = nls.localize('defineKeybinding.start', "Define Keybinding");
const NLS_KB_LAYOUT_ERROR_MESSAGE = nls.localize('defineKeybinding.kbLayoutErrorMessage', "You won't be able to produce this key combination under your current keyboard layout.");
@@ -155,7 +157,7 @@ export class KeybindingWidgetRenderer extends Disposable {
snippetText = smartInsertInfo.prepend + snippetText + smartInsertInfo.append;
this._editor.setPosition(smartInsertInfo.position);
SnippetController2.get(this._editor).insert(snippetText, 0, 0);
SnippetController2.get(this._editor).insert(snippetText, { overwriteBefore: 0, overwriteAfter: 0 });
}
}
}
@@ -400,3 +402,8 @@ function isInterestingEditorModel(editor: ICodeEditor): boolean {
registerEditorContribution(DefineKeybindingController);
registerEditorCommand(new DefineKeybindingCommand());
registerThemingParticipant((theme, collector) => {
collector.addRule(`.monaco-editor .inlineKeybindingInfo:before { background: url("data:image/svg+xml,${SeverityIcon.getSVGData(Severity.Info, theme)}") -0.1em -0.2em no-repeat; }`);
collector.addRule(`.monaco-editor .inlineKeybindingError:before { background: url("data:image/svg+xml,${SeverityIcon.getSVGData(Severity.Error, theme)}") -0.1em -0.2em no-repeat; }`);
});

View File

@@ -0,0 +1,181 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar';
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { IKeymapService, areKeyboardLayoutsEqual, parseKeyboardLayoutDescription, getKeyboardLayoutId, IKeyboardLayoutInfo } from 'vs/workbench/services/keybinding/common/keymapInfo';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { Registry } from 'vs/platform/registry/common/platform';
import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
import { KEYBOARD_LAYOUT_OPEN_PICKER } from 'vs/workbench/contrib/preferences/common/preferences';
import { Action } from 'vs/base/common/actions';
import { isWeb, isMacintosh, isWindows } from 'vs/base/common/platform';
import { QuickPickInput, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IFileService } from 'vs/platform/files/common/files';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { VSBuffer } from 'vs/base/common/buffer';
import { IEditor } from 'vs/workbench/common/editor';
export class KeyboardLayoutPickerContribution extends Disposable implements IWorkbenchContribution {
private readonly pickerElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
constructor(
@IKeymapService private readonly keymapService: IKeymapService,
@IStatusbarService private readonly statusbarService: IStatusbarService,
) {
super();
let layout = this.keymapService.getCurrentKeyboardLayout();
if (layout) {
let layoutInfo = parseKeyboardLayoutDescription(layout);
this.pickerElement.value = this.statusbarService.addEntry(
{
text: nls.localize('keyboardLayout', "Layout: {0}", layoutInfo.label),
command: KEYBOARD_LAYOUT_OPEN_PICKER
},
'status.workbench.keyboardLayout',
nls.localize('status.workbench.keyboardLayout', "Keyboard Layout"),
StatusbarAlignment.RIGHT
);
}
this._register(keymapService.onDidChangeKeyboardMapper(() => {
let layout = this.keymapService.getCurrentKeyboardLayout();
let layoutInfo = parseKeyboardLayoutDescription(layout);
if (this.pickerElement.value) {
this.pickerElement.value.update({
text: nls.localize('keyboardLayout', "Layout: {0}", layoutInfo.label),
command: KEYBOARD_LAYOUT_OPEN_PICKER
});
} else {
this.pickerElement.value = this.statusbarService.addEntry(
{
text: nls.localize('keyboardLayout', "Layout: {0}", layoutInfo.label),
command: KEYBOARD_LAYOUT_OPEN_PICKER
},
'status.workbench.keyboardLayout',
nls.localize('status.workbench.keyboardLayout', "Keyboard Layout"),
StatusbarAlignment.RIGHT
);
}
}));
}
}
const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
workbenchContributionsRegistry.registerWorkbenchContribution(KeyboardLayoutPickerContribution, LifecyclePhase.Starting);
interface LayoutQuickPickItem extends IQuickPickItem {
layout: IKeyboardLayoutInfo;
}
export class KeyboardLayoutPickerAction extends Action {
static readonly ID = KEYBOARD_LAYOUT_OPEN_PICKER;
static readonly LABEL = nls.localize('keyboard.chooseLayout', "Change Keyboard Layout");
private static DEFAULT_CONTENT: string = [
`// ${nls.localize('displayLanguage', 'Defines the keyboard layout used in VS Code in the browser environment.')}`,
`// ${nls.localize('doc', 'Open VS Code and run "Developer: Inspect Key Mappings (JSON)" from Command Palette.')}`,
``,
`// Once you have the keyboard layout info, please paste it below.`,
'\n'
].join('\n');
constructor(
actionId: string,
actionLabel: string,
@IFileService private readonly fileService: IFileService,
@IQuickInputService private readonly quickInputService: IQuickInputService,
@IKeymapService private readonly keymapService: IKeymapService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IEditorService private readonly editorService: IEditorService
) {
super(actionId, actionLabel);
this.enabled = isWeb;
}
async run(): Promise<void> {
let layouts = this.keymapService.getAllKeyboardLayouts();
let currentLayout = this.keymapService.getCurrentKeyboardLayout();
let layoutConfig = this.configurationService.getValue('keyboard.layout');
let isAutoDetect = layoutConfig === 'autodetect';
const picks: QuickPickInput[] = layouts.map(layout => {
const picked = !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout);
const layoutInfo = parseKeyboardLayoutDescription(layout);
return {
layout: layout,
label: [layoutInfo.label, (layout && layout.isUserKeyboardLayout) ? '(User configured layout)' : ''].join(' '),
id: (<any>layout).text || (<any>layout).lang || (<any>layout).layout,
description: layoutInfo.description + (picked ? ' (Current layout)' : ''),
picked: !isAutoDetect && areKeyboardLayoutsEqual(currentLayout, layout)
};
}).sort((a: IQuickPickItem, b: IQuickPickItem) => {
return a.label < b.label ? -1 : (a.label > b.label ? 1 : 0);
});
if (picks.length > 0) {
const platform = isMacintosh ? 'Mac' : isWindows ? 'Win' : 'Linux';
picks.unshift({ type: 'separator', label: nls.localize('layoutPicks', "Keyboard Layouts ({0})", platform) });
}
let configureKeyboardLayout: IQuickPickItem = { label: nls.localize('configureKeyboardLayout', "Configure Keyboard Layout") };
picks.unshift(configureKeyboardLayout);
// Offer to "Auto Detect"
const autoDetectMode: IQuickPickItem = {
label: nls.localize('autoDetect', "Auto Detect"),
description: isAutoDetect ? `Current: ${parseKeyboardLayoutDescription(currentLayout).label}` : undefined,
picked: isAutoDetect ? true : undefined
};
picks.unshift(autoDetectMode);
const pick = await this.quickInputService.pick(picks, { placeHolder: nls.localize('pickKeyboardLayout', "Select Keyboard Layout"), matchOnDescription: true });
if (!pick) {
return;
}
if (pick === autoDetectMode) {
// set keymap service to auto mode
this.configurationService.updateValue('keyboard.layout', 'autodetect');
return;
}
if (pick === configureKeyboardLayout) {
const file = this.environmentService.keyboardLayoutResource;
await this.fileService.resolve(file).then(undefined, (error) => {
return this.fileService.createFile(file, VSBuffer.fromString(KeyboardLayoutPickerAction.DEFAULT_CONTENT));
}).then((stat): Promise<IEditor | null> | null => {
if (!stat) {
return null;
}
return this.editorService.openEditor({
resource: stat.resource,
mode: 'jsonc'
});
}, (error) => {
throw new Error(nls.localize('fail.createSettings', "Unable to create '{0}' ({1}).", file.toString(), error));
});
return Promise.resolve();
}
this.configurationService.updateValue('keyboard.layout', getKeyboardLayoutId((<LayoutQuickPickItem>pick).layout));
}
}
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(KeyboardLayoutPickerAction, KeyboardLayoutPickerAction.ID, KeyboardLayoutPickerAction.LABEL, {}), 'Preferences: Change Keyboard Layout', nls.localize('preferences', "Preferences"));

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="3 3 16 16" enable-background="new 3 3 16 16"><polygon fill="#e8e8e8" points="12.597,11.042 15.4,13.845 13.844,15.4 11.042,12.598 8.239,15.4 6.683,13.845 9.485,11.042 6.683,8.239 8.238,6.683 11.042,9.486 13.845,6.683 15.4,8.239"/></svg>

Before

Width:  |  Height:  |  Size: 307 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="3 3 16 16" enable-background="new 3 3 16 16"><polygon fill="#424242" points="12.597,11.042 15.4,13.845 13.844,15.4 11.042,12.598 8.239,15.4 6.683,13.845 9.485,11.042 6.683,8.239 8.238,6.683 11.042,9.486 13.845,6.683 15.4,8.239"/></svg>

Before

Width:  |  Height:  |  Size: 307 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 7V8H8V14H7V8H1V7H7V1H8V7H14Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 163 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 7V8H8V14H7V8H1V7H7V1H8V7H14Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 163 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 3.76345L5.80687 11.9351L5.08584 11.8927L1 7.29614L1.76345 6.61752L5.50997 10.8324L14.3214 3L15 3.76345Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 278 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 3.76345L5.80687 11.9351L5.08584 11.8927L1 7.29614L1.76345 6.61752L5.50997 10.8324L14.3214 3L15 3.76345Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 278 B

View File

@@ -0,0 +1,7 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 12.6L10.7 13.3L12.3 11.7L13.9 13.3L14.7 12.6L13 11L14.7 9.40005L13.9 8.60005L12.3 10.3L10.7 8.60005L10 9.40005L11.6 11L10 12.6Z" fill="#C5C5C5"/>
<path d="M1 4L15 4L15 3L1 3L1 4Z" fill="#C5C5C5"/>
<path d="M1 7L15 7L15 6L1 6L1 7Z" fill="#C5C5C5"/>
<path d="M9 9.5L9 9L1 9L1 10L9 10L9 9.5Z" fill="#C5C5C5"/>
<path d="M9 13L9 12.5L9 12L1 12L1 13L9 13Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 484 B

View File

@@ -1 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.065 13H15v2H2.056v-2h5.009zm3.661-12H7.385L8.44 2.061 7.505 3H15V1h-4.274zM3.237 9H2.056v2H15V9H3.237zm4.208-4l.995 1-.995 1H15V5H7.445z" fill="#C5C5C5"/><path d="M5.072 4.03L7.032 6 5.978 7.061l-1.96-1.97-1.961 1.97L1 6l1.96-1.97L1 2.061 2.056 1l1.96 1.97L5.977 1l1.057 1.061L5.072 4.03z" fill="#F48771"/></svg>

Before

Width:  |  Height:  |  Size: 419 B

View File

@@ -0,0 +1,7 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M10 12.6L10.7 13.3L12.3 11.7L13.9 13.3L14.7 12.6L13 11L14.7 9.40005L13.9 8.60005L12.3 10.3L10.7 8.60005L10 9.40005L11.6 11L10 12.6Z" fill="#424242"/>
<path d="M1 4L15 4L15 3L1 3L1 4Z" fill="#424242"/>
<path d="M1 7L15 7L15 6L1 6L1 7Z" fill="#424242"/>
<path d="M9 9.5L9 9L1 9L1 10L9 10L9 9.5Z" fill="#424242"/>
<path d="M9 13L9 12.5L9 12L1 12L1 13L9 13Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 484 B

View File

@@ -1 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.065 13H15v2H2.056v-2h5.009zm3.661-12H7.385L8.44 2.061 7.505 3H15V1h-4.274zM3.237 9H2.056v2H15V9H3.237zm4.208-4l.995 1-.995 1H15V5H7.445z" fill="#424242"/><path d="M5.072 4.03L7.032 6 5.978 7.061l-1.96-1.97-1.961 1.97L1 6l1.96-1.97L1 2.061 2.056 1l1.96 1.97L5.977 1l1.057 1.061L5.072 4.03z" fill="#A1260D"/></svg>

Before

Width:  |  Height:  |  Size: 419 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="-1 0 16 16" enable-background="new -1 0 16 16"><path fill="#424242" d="M14 1v9h-1v-8h-8v-1h9zm-11 2v1h8v8h1v-9h-9zm7 2v9h-9v-9h9zm-2 2h-5v5h5v-5z"/><rect x="4" y="9" fill="#00539C" width="3" height="1"/></svg>

Before

Width:  |  Height:  |  Size: 281 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="-1 0 16 16" enable-background="new -1 0 16 16"><path fill="#C5C5C5" d="M14 1v9h-1v-8h-8v-1h9zm-11 2v1h8v8h1v-9h-9zm7 2v9h-9v-9h9zm-2 2h-5v5h5v-5z"/><rect x="4" y="9" fill="#75BEFF" width="3" height="1"/></svg>

Before

Width:  |  Height:  |  Size: 281 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.40706 15L1 13.5929L3.35721 9.46781L3.52339 9.25025L11.7736 1L13.2321 1L15 2.76791V4.22636L6.74975 12.4766L6.53219 12.6428L2.40706 15ZM2.40706 13.5929L6.02053 11.7474L14.2708 3.49714L12.5029 1.72923L4.25262 9.97947L2.40706 13.5929Z" fill="#C5C5C5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.64645 12.3536L3.64645 10.3536L4.35355 9.64648L6.35355 11.6465L5.64645 12.3536Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 553 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.98361V2.97184V2H5.91083C5.59743 2 5.29407 2.06161 5.00128 2.18473C4.70818 2.30798 4.44942 2.48474 4.22578 2.71498C4.00311 2.94422 3.83792 3.19498 3.73282 3.46766L3.73233 3.46898C3.63382 3.7352 3.56814 4.01201 3.53533 4.29917L3.53519 4.30053C3.50678 4.5805 3.4987 4.86844 3.51084 5.16428C3.52272 5.45379 3.52866 5.74329 3.52866 6.03279C3.52866 6.23556 3.48974 6.42594 3.412 6.60507L3.4116 6.60601C3.33687 6.78296 3.23423 6.93866 3.10317 7.07359C2.97644 7.20405 2.82466 7.31055 2.64672 7.3925C2.4706 7.46954 2.28497 7.5082 2.08917 7.5082H2V7.6V8.4V8.4918H2.08917C2.28465 8.4918 2.47001 8.53238 2.64601 8.61334L2.64742 8.61396C2.82457 8.69157 2.97577 8.79762 3.10221 8.93161L3.10412 8.93352C3.23428 9.0637 3.33659 9.21871 3.41129 9.39942L3.41201 9.40108C3.48986 9.58047 3.52866 9.76883 3.52866 9.96721C3.52866 10.2567 3.52272 10.5462 3.51084 10.8357C3.4987 11.1316 3.50677 11.4215 3.53516 11.7055L3.53535 11.7072C3.56819 11.9903 3.63387 12.265 3.73232 12.531L3.73283 12.5323C3.83793 12.805 4.00311 13.0558 4.22578 13.285C4.44942 13.5153 4.70818 13.692 5.00128 13.8153C5.29407 13.9384 5.59743 14 5.91083 14H6V13.2V13.0164H5.91083C5.71095 13.0164 5.52346 12.9777 5.34763 12.9008C5.17396 12.8191 5.02194 12.7126 4.89086 12.5818C4.76386 12.4469 4.66104 12.2911 4.58223 12.1137C4.50838 11.9346 4.47134 11.744 4.47134 11.541C4.47134 11.3127 4.4753 11.0885 4.48321 10.8686C4.49125 10.6411 4.49127 10.4195 4.48324 10.2039C4.47914 9.98246 4.46084 9.76883 4.42823 9.56312C4.39513 9.35024 4.33921 9.14757 4.26039 8.95536C4.18091 8.76157 4.07258 8.57746 3.93616 8.40298C3.82345 8.25881 3.68538 8.12462 3.52283 8C3.68538 7.87538 3.82345 7.74119 3.93616 7.59702C4.07258 7.42254 4.18091 7.23843 4.26039 7.04464C4.33913 6.85263 4.39513 6.65175 4.42826 6.44285C4.46082 6.2333 4.47914 6.01973 4.48324 5.80219C4.49127 5.58262 4.49125 5.36105 4.48321 5.13749C4.4753 4.9134 4.47134 4.68725 4.47134 4.45902C4.47134 4.26019 4.50833 4.07152 4.58238 3.89205C4.66135 3.71034 4.76421 3.55475 4.89086 3.42437C5.02193 3.28942 5.17461 3.18275 5.34802 3.10513C5.5238 3.02427 5.71113 2.98361 5.91083 2.98361H6ZM10 13.0164V13.0282V14H10.0892C10.4026 14 10.7059 13.9384 10.9987 13.8153C11.2918 13.692 11.5506 13.5153 11.7742 13.285C11.9969 13.0558 12.1621 12.805 12.2672 12.5323L12.2677 12.531C12.3662 12.2648 12.4319 11.988 12.4647 11.7008L12.4648 11.6995C12.4932 11.4195 12.5013 11.1316 12.4892 10.8357C12.4773 10.5462 12.4713 10.2567 12.4713 9.96721C12.4713 9.76444 12.5103 9.57406 12.588 9.39493L12.5884 9.39399C12.6631 9.21704 12.7658 9.06134 12.8968 8.92642C13.0236 8.79595 13.1753 8.68945 13.3533 8.6075C13.5294 8.53046 13.715 8.4918 13.9108 8.4918H14V8.4V7.6V7.5082H13.9108C13.7153 7.5082 13.53 7.46762 13.354 7.38666L13.3526 7.38604C13.1754 7.30844 13.0242 7.20238 12.8978 7.06839L12.8959 7.06648C12.7657 6.9363 12.6634 6.78129 12.5887 6.60058L12.588 6.59892C12.5101 6.41953 12.4713 6.23117 12.4713 6.03279C12.4713 5.74329 12.4773 5.45379 12.4892 5.16428C12.5013 4.86842 12.4932 4.57848 12.4648 4.29454L12.4646 4.29285C12.4318 4.00971 12.3661 3.73502 12.2677 3.46897L12.2672 3.46766C12.1621 3.19499 11.9969 2.94422 11.7742 2.71498C11.5506 2.48474 11.2918 2.30798 10.9987 2.18473C10.7059 2.06161 10.4026 2 10.0892 2H10V2.8V2.98361H10.0892C10.2891 2.98361 10.4765 3.0223 10.6524 3.09917C10.826 3.18092 10.9781 3.28736 11.1091 3.41823C11.2361 3.55305 11.339 3.70889 11.4178 3.88628C11.4916 4.0654 11.5287 4.25596 11.5287 4.45902C11.5287 4.68727 11.5247 4.91145 11.5168 5.13142C11.5088 5.35894 11.5087 5.58049 11.5168 5.79605C11.5209 6.01754 11.5392 6.23117 11.5718 6.43688C11.6049 6.64976 11.6608 6.85243 11.7396 7.04464C11.8191 7.23843 11.9274 7.42254 12.0638 7.59702C12.1765 7.74119 12.3146 7.87538 12.4772 8C12.3146 8.12462 12.1765 8.25881 12.0638 8.40298C11.9274 8.57746 11.8191 8.76157 11.7396 8.95536C11.6609 9.14737 11.6049 9.34825 11.5717 9.55715C11.5392 9.7667 11.5209 9.98027 11.5168 10.1978C11.5087 10.4174 11.5087 10.6389 11.5168 10.8625C11.5247 11.0866 11.5287 11.3128 11.5287 11.541C11.5287 11.7398 11.4917 11.9285 11.4176 12.1079C11.3386 12.2897 11.2358 12.4452 11.1091 12.5756C10.9781 12.7106 10.8254 12.8173 10.652 12.8949C10.4762 12.9757 10.2889 13.0164 10.0892 13.0164H10Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M6 2.98361V2.97184V2H5.91083C5.59743 2 5.29407 2.06161 5.00128 2.18473C4.70818 2.30798 4.44942 2.48474 4.22578 2.71498C4.00311 2.94422 3.83792 3.19498 3.73282 3.46766L3.73233 3.46898C3.63382 3.7352 3.56814 4.01201 3.53533 4.29917L3.53519 4.30053C3.50678 4.5805 3.4987 4.86844 3.51084 5.16428C3.52272 5.45379 3.52866 5.74329 3.52866 6.03279C3.52866 6.23556 3.48974 6.42594 3.412 6.60507L3.4116 6.60601C3.33687 6.78296 3.23423 6.93866 3.10317 7.07359C2.97644 7.20405 2.82466 7.31055 2.64672 7.3925C2.4706 7.46954 2.28497 7.5082 2.08917 7.5082H2V7.6V8.4V8.4918H2.08917C2.28465 8.4918 2.47001 8.53238 2.64601 8.61334L2.64742 8.61396C2.82457 8.69157 2.97577 8.79762 3.10221 8.93161L3.10412 8.93352C3.23428 9.0637 3.33659 9.21871 3.41129 9.39942L3.41201 9.40108C3.48986 9.58047 3.52866 9.76883 3.52866 9.96721C3.52866 10.2567 3.52272 10.5462 3.51084 10.8357C3.4987 11.1316 3.50677 11.4215 3.53516 11.7055L3.53535 11.7072C3.56819 11.9903 3.63387 12.265 3.73232 12.531L3.73283 12.5323C3.83793 12.805 4.00311 13.0558 4.22578 13.285C4.44942 13.5153 4.70818 13.692 5.00128 13.8153C5.29407 13.9384 5.59743 14 5.91083 14H6V13.2V13.0164H5.91083C5.71095 13.0164 5.52346 12.9777 5.34763 12.9008C5.17396 12.8191 5.02194 12.7126 4.89086 12.5818C4.76386 12.4469 4.66104 12.2911 4.58223 12.1137C4.50838 11.9346 4.47134 11.744 4.47134 11.541C4.47134 11.3127 4.4753 11.0885 4.48321 10.8686C4.49125 10.6411 4.49127 10.4195 4.48324 10.2039C4.47914 9.98246 4.46084 9.76883 4.42823 9.56312C4.39513 9.35024 4.33921 9.14757 4.26039 8.95536C4.18091 8.76157 4.07258 8.57746 3.93616 8.40298C3.82345 8.25881 3.68538 8.12462 3.52283 8C3.68538 7.87538 3.82345 7.74119 3.93616 7.59702C4.07258 7.42254 4.18091 7.23843 4.26039 7.04464C4.33913 6.85263 4.39513 6.65175 4.42826 6.44285C4.46082 6.2333 4.47914 6.01973 4.48324 5.80219C4.49127 5.58262 4.49125 5.36105 4.48321 5.13749C4.4753 4.9134 4.47134 4.68725 4.47134 4.45902C4.47134 4.26019 4.50833 4.07152 4.58238 3.89205C4.66135 3.71034 4.76421 3.55475 4.89086 3.42437C5.02193 3.28942 5.17461 3.18275 5.34802 3.10513C5.5238 3.02427 5.71113 2.98361 5.91083 2.98361H6ZM10 13.0164V13.0282V14H10.0892C10.4026 14 10.7059 13.9384 10.9987 13.8153C11.2918 13.692 11.5506 13.5153 11.7742 13.285C11.9969 13.0558 12.1621 12.805 12.2672 12.5323L12.2677 12.531C12.3662 12.2648 12.4319 11.988 12.4647 11.7008L12.4648 11.6995C12.4932 11.4195 12.5013 11.1316 12.4892 10.8357C12.4773 10.5462 12.4713 10.2567 12.4713 9.96721C12.4713 9.76444 12.5103 9.57406 12.588 9.39493L12.5884 9.39399C12.6631 9.21704 12.7658 9.06134 12.8968 8.92642C13.0236 8.79595 13.1753 8.68945 13.3533 8.6075C13.5294 8.53046 13.715 8.4918 13.9108 8.4918H14V8.4V7.6V7.5082H13.9108C13.7153 7.5082 13.53 7.46762 13.354 7.38666L13.3526 7.38604C13.1754 7.30844 13.0242 7.20238 12.8978 7.06839L12.8959 7.06648C12.7657 6.9363 12.6634 6.78129 12.5887 6.60058L12.588 6.59892C12.5101 6.41953 12.4713 6.23117 12.4713 6.03279C12.4713 5.74329 12.4773 5.45379 12.4892 5.16428C12.5013 4.86842 12.4932 4.57848 12.4648 4.29454L12.4646 4.29285C12.4318 4.00971 12.3661 3.73502 12.2677 3.46897L12.2672 3.46766C12.1621 3.19499 11.9969 2.94422 11.7742 2.71498C11.5506 2.48474 11.2918 2.30798 10.9987 2.18473C10.7059 2.06161 10.4026 2 10.0892 2H10V2.8V2.98361H10.0892C10.2891 2.98361 10.4765 3.0223 10.6524 3.09917C10.826 3.18092 10.9781 3.28736 11.1091 3.41823C11.2361 3.55305 11.339 3.70889 11.4178 3.88628C11.4916 4.0654 11.5287 4.25596 11.5287 4.45902C11.5287 4.68727 11.5247 4.91145 11.5168 5.13142C11.5088 5.35894 11.5087 5.58049 11.5168 5.79605C11.5209 6.01754 11.5392 6.23117 11.5718 6.43688C11.6049 6.64976 11.6608 6.85243 11.7396 7.04464C11.8191 7.23843 11.9274 7.42254 12.0638 7.59702C12.1765 7.74119 12.3146 7.87538 12.4772 8C12.3146 8.12462 12.1765 8.25881 12.0638 8.40298C11.9274 8.57746 11.8191 8.76157 11.7396 8.95536C11.6609 9.14737 11.6049 9.34825 11.5717 9.55715C11.5392 9.7667 11.5209 9.98027 11.5168 10.1978C11.5087 10.4174 11.5087 10.6389 11.5168 10.8625C11.5247 11.0866 11.5287 11.3128 11.5287 11.541C11.5287 11.7398 11.4917 11.9285 11.4176 12.1079C11.3386 12.2897 11.2358 12.4452 11.1091 12.5756C10.9781 12.7106 10.8254 12.8173 10.652 12.8949C10.4762 12.9757 10.2889 13.0164 10.0892 13.0164H10Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,4 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.40706 15L1 13.5929L3.35721 9.46781L3.52339 9.25025L11.7736 1L13.2321 1L15 2.76791V4.22636L6.74975 12.4766L6.53219 12.6428L2.40706 15ZM2.40706 13.5929L6.02053 11.7474L14.2708 3.49714L12.5029 1.72923L4.25262 9.97947L2.40706 13.5929Z" fill="#424242"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.64645 12.3536L3.64645 10.3536L4.35355 9.64648L6.35355 11.6465L5.64645 12.3536Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 553 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><path d="M8 1c-3.865 0-7 3.135-7 7s3.135 7 7 7 7-3.135 7-7-3.135-7-7-7zm1 12h-2v-7h2v7zm0-8h-2v-2h2v2z" fill="#1BA1E2"/><path d="M7 6h2v7h-2v-7zm0-1h2v-2h-2v2z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 243 B

View File

@@ -47,7 +47,6 @@
display:inline-block;
height:0.8em;
width:1em;
background: url(info.svg) 0px -0.1em no-repeat;
background-size: 0.9em;
}
@@ -57,7 +56,6 @@
display:inline-block;
height:0.8em;
width:1em;
background: url(status-error.svg) 0px -0.1em no-repeat;
background-size: 1em;
}

View File

@@ -46,30 +46,30 @@
}
.keybindings-editor .monaco-action-bar .action-item > .sort-by-precedence {
background: url('sort_precedence.svg') center center no-repeat;
background: url('sort-precedence-light.svg') center center no-repeat;
}
.hc-black .keybindings-editor .monaco-action-bar .action-item > .sort-by-precedence,
.vs-dark .keybindings-editor .monaco-action-bar .action-item > .sort-by-precedence {
background: url('sort_precedence_inverse.svg') center center no-repeat;
background: url('sort-precedence-dark.svg') center center no-repeat;
}
.keybindings-editor .monaco-action-bar .action-item > .record-keys {
background: url('record-keys.svg') center center no-repeat;
background: url('record-keys-light.svg') center center no-repeat;
}
.hc-black .keybindings-editor .monaco-action-bar .action-item > .record-keys,
.vs-dark .keybindings-editor .monaco-action-bar .action-item > .record-keys {
background: url('record-keys-inverse.svg') center center no-repeat;
background: url('record-keys-dark.svg') center center no-repeat;
}
.keybindings-editor .monaco-action-bar .action-item > .clear-input {
background: url('clear.svg') center center no-repeat;
background: url('clear-light.svg') center center no-repeat;
}
.hc-black .keybindings-editor .monaco-action-bar .action-item > .clear-input,
.vs-dark .keybindings-editor .monaco-action-bar .action-item > .clear-input {
background: url('clear-inverse.svg') center center no-repeat;
background: url('clear-dark.svg') center center no-repeat;
}
.keybindings-editor > .keybindings-header .open-keybindings-container {
@@ -208,20 +208,20 @@
}
.keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list-row > .column .monaco-action-bar .action-item > .icon.edit {
background: url('edit.svg') center center no-repeat;
background: url('edit-light.svg') center center no-repeat;
transform: rotate(-90deg);
}
.hc-black .keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list-row > .column .monaco-action-bar .action-item > .icon.edit,
.vs-dark .keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list-row > .column .monaco-action-bar .action-item > .icon.edit {
background: url('edit_inverse.svg') center center no-repeat;
background: url('edit-dark.svg') center center no-repeat;
}
.keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list-row > .column .monaco-action-bar .action-item > .icon.add {
background: url('add.svg') center center no-repeat;
background: url('add-light.svg') center center no-repeat;
}
.hc-black .keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list-row > .column .monaco-action-bar .action-item > .icon.add,
.vs-dark .keybindings-editor > .keybindings-body > .keybindings-list-container .monaco-list-row > .column .monaco-action-bar .action-item > .icon.add {
background: url('add_inverse.svg') center center no-repeat;
background: url('add-dark.svg') center center no-repeat;
}

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.06065 3.85356L5.91421 6L5.2071 5.29289L6.49999 4H3.5C3.10218 4 2.72064 4.15804 2.43934 4.43934C2.15804 4.72065 2 5.10218 2 5.5C2 5.89783 2.15804 6.27936 2.43934 6.56066C2.72064 6.84197 3.10218 7 3.5 7H4V8H3.5C2.83696 8 2.20107 7.73661 1.73223 7.26777C1.26339 6.79893 1 6.16305 1 5.5C1 4.83696 1.26339 4.20108 1.73223 3.73224C2.20107 3.2634 2.83696 3 3.5 3H6.49999L6.49999 3H6.49996L6 2.50004V2.50001L5.2071 1.70711L5.91421 1L8.06065 3.14645L8.06065 3.85356ZM5 6.50003L5.91421 7.41424L6 7.32845V14H14V7H10V3H9.06065V2.73227L8.32838 2H11.2L11.5 2.1L14.9 5.6L15 6V14.5L14.5 15H5.5L5 14.5V9.00003V6.50003ZM11 3V6H13.9032L11 3Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 796 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.06065 3.85356L5.91421 6L5.2071 5.29289L6.49999 4H3.5C3.10218 4 2.72064 4.15804 2.43934 4.43934C2.15804 4.72065 2 5.10218 2 5.5C2 5.89783 2.15804 6.27936 2.43934 6.56066C2.72064 6.84197 3.10218 7 3.5 7H4V8H3.5C2.83696 8 2.20107 7.73661 1.73223 7.26777C1.26339 6.79893 1 6.16305 1 5.5C1 4.83696 1.26339 4.20108 1.73223 3.73224C2.20107 3.2634 2.83696 3 3.5 3H6.49999L6.49999 3H6.49996L6 2.50004V2.50001L5.2071 1.70711L5.91421 1L8.06065 3.14645L8.06065 3.85356ZM5 6.50003L5.91421 7.41424L6 7.32845V14H14V7H10V3H9.06065V2.73227L8.32838 2H11.2L11.5 2.1L14.9 5.6L15 6V14.5L14.5 15H5.5L5 14.5V9.00003V6.50003ZM11 3V6H13.9032L11 3Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 796 B

View File

@@ -199,27 +199,28 @@
}
.monaco-editor .settings-group-title-widget .title-container .expand-collapse-icon {
background: url(expanded.svg) 50% 50% no-repeat;
background: url("tree-expanded-light.svg") 50% 50% no-repeat;
margin-right: 2px;
width: 16px;
height: 100%;
}
.monaco-editor.vs-dark .settings-group-title-widget .title-container .expand-collapse-icon,
.monaco-editor.hc-black .settings-group-title-widget .title-container .expand-collapse-icon {
background: url(expanded-dark.svg) 50% 50% no-repeat;
background: url("tree-expanded-dark.svg") 50% 50% no-repeat;
}
.monaco-editor .settings-group-title-widget .title-container.collapsed .expand-collapse-icon {
background: url(collapsed.svg) 50% 50% no-repeat;
background: url("tree-collapsed-light.svg") 50% 50% no-repeat;
}
.monaco-editor.vs-dark .settings-group-title-widget .title-container.collapsed .expand-collapse-icon,
.monaco-editor.hc-black .settings-group-title-widget .title-container.collapsed .expand-collapse-icon {
background: url(collapsed-dark.svg) 50% 50% no-repeat;
background: url("tree-collapsed-dark.svg") 50% 50% no-repeat;
}
.monaco-editor .edit-preferences-widget {
background: url('edit.svg') center center no-repeat;
background: url('edit-light.svg') center center no-repeat;
transform: rotate(-90deg);
width:16px;
height: 16px;
@@ -233,16 +234,7 @@
.monaco-editor.hc-black .edit-preferences-widget,
.monaco-editor.vs-dark .edit-preferences-widget {
background: url('edit_inverse.svg') center center no-repeat;
}
.monaco-editor .unsupportedWorkbenhSettingInfo:before {
content:" ";
display:inline-block;
height:1em;
width:1em;
background: url(info.svg) 50% 50% no-repeat;
background-size: 0.9em;
background: url('edit-dark.svg') center center no-repeat;
}
.monaco-editor .dim-configuration {
@@ -253,14 +245,4 @@
padding: 10px;
border-radius: 5px;
cursor: pointer;
}
.title-actions .action-item .icon.collapseAll,
.editor-actions .action-item .icon.collapseAll {
background: url('collapseAll.svg') center center no-repeat;
}
.vs-dark .title-actions .action-item .icon.collapseAll,
.vs-dark .editor-actions .action-item .icon.collapseAll {
background: url('collapseAll_inverse.svg') center center no-repeat;
}
}

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 4H3L3 11H14V4ZM3 3C2.44772 3 2 3.44772 2 4V11C2 11.5523 2.44772 12 3 12H14C14.5523 12 15 11.5523 15 11V4C15 3.44772 14.5523 3 14 3H3ZM4 5H5V6H4V5ZM7 5H6V6H7V5ZM8 5H9V6H8V5ZM11 5H10V6H11V5ZM12 5H13V6H12V5ZM6 8V7H4V8H6ZM7 7H8V8H7V7ZM10 7H9V8H10V7ZM13 7V8H11V7H13ZM5 9H4V10H5V9ZM6 9H11V10H6V9ZM13 9H12V10H13V9Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 482 B

View File

@@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 5H9V4H10V5V5ZM3 6H2V7H3V6V6ZM8 4H7V5H8V4V4ZM4 4H2V5H4V4V4ZM12 11H14V10H12V11V11ZM8 7H9V6H8V7V7ZM4 10H2V11H4V10V10ZM12 4H11V5H12V4V4ZM14 4H13V5H14V4V4ZM12 9H14V6H12V9V9ZM16 3V12C16 12.55 15.55 13 15 13H1C0.45 13 0 12.55 0 12V3C0 2.45 0.45 2 1 2H15C15.55 2 16 2.45 16 3V3ZM15 3H1V12H15V3V3ZM6 7H7V6H6V7V7ZM6 4H5V5H6V4V4ZM4 7H5V6H4V7V7ZM5 11H11V10H5V11V11ZM10 7H11V6H10V7V7ZM3 8H2V9H3V8V8ZM8 8V9H9V8H8V8ZM6 8V9H7V8H6V8ZM5 8H4V9H5V8V8ZM10 9H11V8H10V9V9Z" fill="#C5C5C5"/>
</svg>

Before

Width:  |  Height:  |  Size: 624 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M14 4H3L3 11H14V4ZM3 3C2.44772 3 2 3.44772 2 4V11C2 11.5523 2.44772 12 3 12H14C14.5523 12 15 11.5523 15 11V4C15 3.44772 14.5523 3 14 3H3ZM4 5H5V6H4V5ZM7 5H6V6H7V5ZM8 5H9V6H8V5ZM11 5H10V6H11V5ZM12 5H13V6H12V5ZM6 8V7H4V8H6ZM7 7H8V8H7V7ZM10 7H9V8H10V7ZM13 7V8H11V7H13ZM5 9H4V10H5V9ZM6 9H11V10H6V9ZM13 9H12V10H13V9Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 482 B

View File

@@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 5H9V4H10V5V5ZM3 6H2V7H3V6V6ZM8 4H7V5H8V4V4ZM4 4H2V5H4V4V4ZM12 11H14V10H12V11V11ZM8 7H9V6H8V7V7ZM4 10H2V11H4V10V10ZM12 4H11V5H12V4V4ZM14 4H13V5H14V4V4ZM12 9H14V6H12V9V9ZM16 3V12C16 12.55 15.55 13 15 13H1C0.45 13 0 12.55 0 12V3C0 2.45 0.45 2 1 2H15C15.55 2 16 2.45 16 3V3ZM15 3H1V12H15V3V3ZM6 7H7V6H6V7V7ZM6 4H5V5H6V4V4ZM4 7H5V6H4V7V7ZM5 11H11V10H5V11V11ZM10 7H11V6H10V7V7ZM3 8H2V9H3V8V8ZM8 8V9H9V8H8V8ZM6 8V9H7V8H6V8ZM5 8H4V9H5V8V8ZM10 9H11V8H10V9V9Z" fill="#424242"/>
</svg>

Before

Width:  |  Height:  |  Size: 624 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 8.70714L11.6464 12.3536L12.3536 11.6465L8.70711 8.00004L12.3536 4.35359L11.6464 3.64648L8 7.29293L4.35355 3.64648L3.64645 4.35359L7.29289 8.00004L3.64645 11.6465L4.35355 12.3536L8 8.70714Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 362 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8 8.70714L11.6464 12.3536L12.3536 11.6465L8.70711 8.00004L12.3536 4.35359L11.6464 3.64648L8 7.29293L4.35355 3.64648L3.64645 4.35359L7.29289 8.00004L3.64645 11.6465L4.35355 12.3536L8 8.70714Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 362 B

View File

@@ -0,0 +1,514 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.editor-instance#workbench\.editor\.settings2:focus {
outline: none;
}
.settings-editor {
padding: 11px 0px 0px;
overflow: hidden;
}
/* header styling */
.settings-editor > .settings-header {
box-sizing: border-box;
margin: auto;
overflow: hidden;
padding-top: 3px;
padding-left: 24px;
padding-right: 24px;
max-width: 1000px;
}
.settings-editor > .settings-header > .search-container {
position: relative;
}
.vs .settings-editor > .settings-header > .search-container > .suggest-input-container {
border: 1px solid #ddd;
}
.settings-editor > .settings-header > .search-container > .settings-count-widget {
margin: 6px 0px;
padding: 0px 8px;
border-radius: 2px;
position: absolute;
right: 10px;
top: 0;
}
.settings-editor > .settings-header > .settings-header-controls {
height: 32px;
display: flex;
border-bottom: solid 1px;
margin-top: 10px;
}
.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label {
opacity: 0.9;
}
.settings-editor .settings-tabs-widget > .monaco-action-bar .action-item .action-details {
opacity: 0.9;
}
.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label:hover {
opacity: 1;
}
.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget .action-label.checked {
opacity: 1;
}
.vs .settings-editor > .settings-header > .settings-header-controls {
border-color: #cccccc;
}
.vs-dark .settings-editor > .settings-header > .settings-header-controls {
border-color: #3c3c3c;
}
.settings-editor > .settings-header .settings-tabs-widget > .monaco-action-bar .action-item .action-label {
margin-right: 0px;
}
.settings-editor > .settings-header .settings-tabs-widget .monaco-action-bar .action-item .dropdown-icon {
/** The tab widget container height is shorter than elsewhere, need to tweak this */
padding-top: 3px;
}
.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget > .monaco-action-bar .action-item {
padding: 0px;
/* padding must be on action-label because it has the bottom-border, because that's where the .checked class is */
}
.settings-editor > .settings-header > .settings-header-controls .settings-tabs-widget > .monaco-action-bar .action-item .action-label {
text-transform: none;
font-size: 13px;
padding-bottom: 7px;
padding-top: 7px;
padding-left: 8px;
padding-right: 8px;
}
.settings-editor > .settings-body {
position: relative;
}
.settings-editor > .settings-body > .no-results-message {
display: none;
max-width: 1000px;
margin: auto;
margin-top: 20px;
padding-left: 24px;
padding-right: 24px;
box-sizing: border-box;
}
.settings-editor.no-results > .settings-body .settings-toc-container,
.settings-editor.no-results > .settings-body .settings-tree-container {
display: none;
}
.settings-editor.no-results > .settings-body > .no-results-message {
display: block;
}
.settings-editor > .settings-body > .no-results-message a.prominent {
text-decoration: underline;
}
.settings-editor.no-toc-search > .settings-body .settings-tree-container .monaco-list-row .monaco-tl-contents,
.settings-editor.narrow-width > .settings-body .settings-tree-container .monaco-list-row .monaco-tl-contents {
padding-left: 33px;
}
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .monaco-tl-twistie {
/* Hide twisties */
display: none !important;
}
.settings-editor.mid-width > .settings-body > .settings-tree-container .shadow.top {
left: 0;
width: calc(100% - 48px);
margin-left: 24px;
}
.settings-editor > .settings-body > .settings-tree-container .shadow.top {
left: 50%;
max-width: 952px;
/* 1000 - 24*2 padding */
margin-left: -476px;
z-index: 1000;
}
.settings-editor > .settings-body .settings-tree-container .setting-toolbar-container {
position: absolute;
left: -32px;
top: 11px;
bottom: 0px;
width: 26px;
}
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .mouseover .setting-toolbar-container > .monaco-toolbar .toolbar-toggle-more,
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .setting-item.focused .setting-toolbar-container > .monaco-toolbar .toolbar-toggle-more,
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .setting-toolbar-container:hover > .monaco-toolbar .toolbar-toggle-more,
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .setting-toolbar-container > .monaco-toolbar .active .toolbar-toggle-more {
opacity: 1;
}
.settings-editor > .settings-body .settings-tree-container .setting-toolbar-container > .monaco-toolbar .toolbar-toggle-more {
opacity: 0;
transition: opacity .3s;
width: 22px;
height: 22px;
background-position: center;
background-repeat: no-repeat;
background-size: 16px;
}
.vs .settings-editor > .settings-body .settings-tree-container .monaco-toolbar .toolbar-toggle-more {
background-image: url('configure-light.svg');
}
.vs-dark .settings-editor > .settings-body .settings-tree-container .monaco-toolbar .toolbar-toggle-more {
background-image: url('configure-dark.svg');
}
.settings-editor > .settings-body .settings-toc-container {
width: 100%;
pointer-events: none;
z-index: 100;
position: absolute;
}
.settings-editor > .settings-body .settings-toc-container .monaco-list {
width: 160px;
pointer-events: initial;
}
.settings-editor.no-toc-search > .settings-body .settings-toc-container,
.settings-editor.narrow-width > .settings-body .settings-toc-container {
display: none;
}
.settings-editor > .settings-body .settings-toc-container .monaco-scrollable-element > .shadow {
display: none;
}
.settings-editor > .settings-body .settings-toc-container .monaco-list-row .monaco-tl-contents {
display: flex;
}
.settings-editor > .settings-body .settings-toc-container .monaco-list-row .settings-toc-entry {
overflow: hidden;
text-overflow: ellipsis;
line-height: 22px;
opacity: 0.9;
flex-shrink: 1;
}
.settings-editor > .settings-body .settings-toc-container .monaco-list-row .settings-toc-count {
display: none;
line-height: 22px;
opacity: 0.7;
margin-left: 3px;
}
.settings-editor.search-mode > .settings-body .settings-toc-container .monaco-list-row .settings-toc-count {
display: block;
}
.settings-editor > .settings-body .settings-toc-container .monaco-list-row .monaco-tl-twistie {
opacity: 0.9;
}
.settings-editor > .settings-body .settings-toc-container .monaco-list-row.selected .monaco-tl-twistie {
opacity: 1;
}
.settings-editor > .settings-body .settings-toc-container .monaco-list-row.selected .settings-toc-entry {
font-weight: bold;
opacity: 1;
}
.settings-editor > .settings-body .settings-tree-container {
margin-top: 14px;
border-spacing: 0;
border-collapse: separate;
position: relative;
}
.settings-editor > .settings-body .settings-toc-wrapper {
padding-left: 31px;
}
.settings-editor > .settings-body .settings-toc-wrapper {
height: 100%;
max-width: 1000px;
margin: auto;
}
.settings-editor.no-toc-search > .settings-body .settings-tree-container,
.settings-editor.narrow-width > .settings-body .settings-tree-container {
margin-left: 0px;
}
.settings-editor > .settings-body > .settings-tree-container .monaco-list-row {
line-height: 1.4em !important;
/* so validation messages don't get clipped */
overflow: visible;
cursor: default;
}
.settings-editor > .settings-body .settings-tree-container .monaco-list-rows {
overflow: visible !important; /* Allow validation errors to flow out of the tree container. Override inline style from ScrollableElement. */
}
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .monaco-tl-contents {
max-width: 1000px;
margin: auto;
box-sizing: border-box;
padding-left: 217px;
padding-right: 20px;
overflow: visible;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents {
position: relative;
padding-top: 12px;
padding-bottom: 18px;
white-space: normal;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
/* size to contents for hover to show context button */
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-modified-indicator {
display: none;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents.is-configured .setting-item-modified-indicator {
display: block;
content: ' ';
position: absolute;
width: 6px;
border-left-width: 2px;
border-left-style: solid;
left: -9px;
top: 15px;
bottom: 16px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-item-contents.is-configured .setting-item-modified-indicator {
bottom: 23px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-title .setting-item-overrides {
opacity: 0.5;
font-style: italic;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-title .setting-item-overrides a.modified-scope {
text-decoration: underline;
cursor: pointer;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-label {
margin-right: 7px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-cat-label-container {
float: left;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-label,
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-category {
font-weight: 600;
user-select: text;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-category {
opacity: 0.9;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-deprecation-message {
margin-top: 3px;
user-select: text;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-description {
margin-top: -1px;
user-select: text;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-deprecation-message {
position: absolute;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-validation-message {
display: none;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-contents.invalid-input .setting-item-validation-message {
display: block;
position: absolute;
padding: 5px;
box-sizing: border-box;
margin-top: -1px;
z-index: 1;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text .setting-item-validation-message {
width: 500px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-number .setting-item-validation-message {
width: 200px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-number input[type=number]::-webkit-inner-spin-button {
/* Hide arrow button that shows in type=number fields */
-webkit-appearance: none !important;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-description-markdown * {
margin: 0px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-description-markdown a:focus {
outline: 1px solid -webkit-focus-ring-color;
outline-offset: -1px;
text-decoration: underline;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-description-markdown a:hover {
text-decoration: underline;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-description-markdown code {
line-height: 15px;
/** For some reason, this is needed, otherwise <code> will take up 20px height */
font-family: var(--monaco-monospace-font);
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-enumDescription {
display: none;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-enumDescription {
display: block;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-item-contents {
padding-bottom: 26px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-item-value-description {
display: flex;
cursor: pointer;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox {
height: 18px;
width: 18px;
border: 1px solid transparent;
border-radius: 3px;
margin-right: 9px;
margin-left: 0px;
padding: 0px;
background-size: 16px !important;
}
.vs .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked {
background: url('check-light.svg') center center no-repeat;
}
.vs-dark .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked,
.hc-black .settings-editor > .settings-body > .settings-tree-container .setting-item-bool .setting-value-checkbox.checked {
background: url('check-dark.svg') center center no-repeat;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-value {
margin-top: 9px;
display: flex;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-number .setting-item-value > .setting-item-control {
min-width: 200px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text .setting-item-control {
width: 500px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-enum .setting-item-value > .setting-item-control,
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-text .setting-item-value > .setting-item-control {
min-width: initial;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-enum .setting-item-value > .setting-item-control > select {
width: 320px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-value .edit-in-settings-button,
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-value .edit-in-settings-button:hover,
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-value .edit-in-settings-button:active {
text-align: left;
text-decoration: underline;
padding-left: 0px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .monaco-select-box {
width: initial;
font: inherit;
height: 26px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-new-extensions {
display: flex;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-new-extensions .settings-new-extensions-button {
margin: auto;
width: initial;
padding: 4px 10px;
}
.settings-editor > .settings-body > .settings-tree-container .group-title {
cursor: default;
}
.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label {
margin: 0px;
font-weight: 600;
}
.settings-editor > .settings-body > .settings-tree-container .settings-group-level-1 {
padding-top: 23px;
font-size: 24px;
}
.settings-editor > .settings-body > .settings-tree-container .settings-group-level-2 {
padding-top: 32px;
font-size: 20px;
}
.settings-editor > .settings-body > .settings-tree-container .settings-group-level-1.settings-group-first {
padding-top: 7px;
}
.settings-editor.search-mode > .settings-body .settings-toc-container .monaco-list-row .settings-toc-count {
display: block;
}

View File

@@ -3,105 +3,105 @@
* Licensed under the Source EULA. 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 {
background: url(edit.svg) center center no-repeat;
.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 {
background: url(edit_inverse.svg) center center no-repeat;
.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 {
background: url(action-remove.svg) center center no-repeat;
.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 {
background: url(action-remove-dark.svg) center center no-repeat;
.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;
}

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 2L6 3V6H7V3H14V5.45306L14.2071 5.29286L15 6.08576V3L14 2H7ZM8 4H10V6H8V4ZM5 9H3V11H5V9ZM2 7L1 8V13L2 14H9L10 13V8L9 7H2ZM2 13V8H9V13H2ZM8 10H6V12H8V10ZM13 4H12V7.86388L10.818 6.68192L10.1109 7.38903L12.1465 9.42454L12.8536 9.42454L14.889 7.38908L14.1819 6.68197L13 7.86388V4Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 449 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7 2L6 3V6H7V3H14V5.45306L14.2071 5.29286L15 6.08576V3L14 2H7ZM8 4H10V6H8V4ZM5 9H3V11H5V9ZM2 7L1 8V13L2 14H9L10 13V8L9 7H2ZM2 13V8H9V13H2ZM8 10H6V12H8V10ZM13 4H12V7.86388L10.818 6.68192L10.1109 7.38903L12.1465 9.42454L12.8536 9.42454L14.889 7.38908L14.1819 6.68197L13 7.86388V4Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 449 B

View File

@@ -1 +0,0 @@
<svg fill="none" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1v5h-5v9h11v-2.586l1 1 4-4v-8.414zm5 3v2l-2-1.414v-.586zm-2 8h-5v-3h5z" fill="#f6f6f6"/><g fill="#424242"><path d="m3 9h2v2h-2zm3 1h2v2h-2zm8-7v3h.586l.414-.414v-3.586h-9v4h1v-3z"/><path d="m9 10.414v2.586h-7v-5h6v-1h-7v7h9v-2.586zm.414-4.414h.586v-2h-2v.586z"/><path d="m13 5h-2v4l-2-2v2l3 3 3-3v-2l-2 2z"/></g><path d="m8 9.414v-1.414h-6v5h7v-2.586zm-3 1.586h-2v-2h2zm3 1h-2v-2h2zm0-7.414v-.586h6v-1h-7v3h1z" fill="#f0eff1"/></svg>

Before

Width:  |  Height:  |  Size: 540 B

View File

@@ -1 +0,0 @@
<svg fill="none" height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5 1v5h-5v9h11v-2.586l1 1 4-4v-8.414zm5 3v2l-2-1.414v-.586zm-2 8h-5v-3h5z" fill="#2d2d30"/><g fill="#c5c5c5"><path d="m3 9h2v2h-2zm3 1h2v2h-2zm8-7v3h.586l.414-.414v-3.586h-9v4h1v-3z"/><path d="m9 10.414v2.586h-7v-5h6v-1h-7v7h9v-2.586zm.414-4.414h.586v-2h-2v.586z"/><path d="m13 5h-2v4l-2-2v2l3 3 3-3v-2l-2 2z"/></g><path d="m8 9.414v-1.414h-6v5h7v-2.586zm-3 1.586h-2v-2h2zm3 1h-2v-2h2zm0-7.414v-.586h6v-1h-7v3h1z" fill="#2b282e"/></svg>

Before

Width:  |  Height:  |  Size: 540 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16" height="16" width="16"><circle cx="8" cy="8" r="6" fill="#F6F6F6"/><path d="M8 3C5.238 3 3 5.238 3 8s2.238 5 5 5 5-2.238 5-5-2.238-5-5-5zm3 7l-1 1-2-2-2 2-1-1 2-2.027L5 6l1-1 2 2 2-2 1 1-2 1.973L11 10z" fill="#E51400"/><path fill="#fff" d="M11 6l-1-1-2 2-2-2-1 1 2 1.973L5 10l1 1 2-2 2 2 1-1-2-2.027z"/></svg>

Before

Width:  |  Height:  |  Size: 403 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0719 8.00005L5.71461 12.3574L6.33333 12.9761L11 8.30941V7.69069L6.33333 3.02402L5.71461 3.64274L10.0719 8.00005Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 287 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0719 8.00005L5.71461 12.3574L6.33333 12.9761L11 8.30941V7.69069L6.33333 3.02402L5.71461 3.64274L10.0719 8.00005Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 287 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.97603 10.0719L12.3333 5.7146L12.9521 6.33332L8.28539 11L7.66667 11L3 6.33332L3.61872 5.7146L7.97603 10.0719Z" fill="#C5C5C5"/>
</svg>

After

Width:  |  Height:  |  Size: 282 B

View File

@@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.97603 10.0719L12.3333 5.7146L12.9521 6.33332L8.28539 11L7.66667 11L3 6.33332L3.61872 5.7146L7.97603 10.0719Z" fill="#424242"/>
</svg>

After

Width:  |  Height:  |  Size: 282 B

View File

@@ -0,0 +1,866 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import 'vs/css!../browser/media/preferences';
import { Command } from 'vs/editor/browser/editorExtensions';
import { Context as SuggestContext } from 'vs/editor/contrib/suggest/suggest';
import * as nls from 'vs/nls';
import { MenuId, MenuRegistry, SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { WorkbenchStateContext, RemoteAuthorityContext, IsMacNativeContext } from 'vs/workbench/browser/contextkeys';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { Registry } from 'vs/platform/registry/common/platform';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { EditorDescriptor, Extensions as EditorExtensions, IEditorRegistry } from 'vs/workbench/browser/editor';
import { Extensions, IWorkbenchActionRegistry } from 'vs/workbench/common/actions';
import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
import { EditorInput, Extensions as EditorInputExtensions, IEditorInputFactory, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor';
import { ResourceContextKey } from 'vs/workbench/common/resources';
import { KeybindingsEditor } from 'vs/workbench/contrib/preferences/browser/keybindingsEditor';
import { ConfigureLanguageBasedSettingsAction, OpenDefaultKeybindingsFileAction, OpenFolderSettingsAction, OpenGlobalKeybindingsAction, OpenGlobalKeybindingsFileAction, OpenGlobalSettingsAction, OpenRawDefaultSettingsAction, OpenSettings2Action, OpenSettingsJsonAction, OpenWorkspaceSettingsAction, OPEN_FOLDER_SETTINGS_COMMAND, OPEN_FOLDER_SETTINGS_LABEL, OpenRemoteSettingsAction } from 'vs/workbench/contrib/preferences/browser/preferencesActions';
import { PreferencesEditor } from 'vs/workbench/contrib/preferences/browser/preferencesEditor';
import { CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDINGS_SEARCH_FOCUS, CONTEXT_KEYBINDING_FOCUS, CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_JSON_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, CONTEXT_TOC_ROW_FOCUS, IKeybindingsEditor, KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, KEYBINDINGS_EDITOR_COMMAND_COPY, KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND, KEYBINDINGS_EDITOR_COMMAND_DEFINE, KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS, KEYBINDINGS_EDITOR_COMMAND_RECORD_SEARCH_KEYS, KEYBINDINGS_EDITOR_COMMAND_REMOVE, KEYBINDINGS_EDITOR_COMMAND_RESET, KEYBINDINGS_EDITOR_COMMAND_SEARCH, KEYBINDINGS_EDITOR_COMMAND_SHOW_SIMILAR, KEYBINDINGS_EDITOR_COMMAND_SORTBY_PRECEDENCE, KEYBINDINGS_EDITOR_SHOW_DEFAULT_KEYBINDINGS, KEYBINDINGS_EDITOR_SHOW_USER_KEYBINDINGS, MODIFIED_SETTING_TAG, SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS, SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING, SETTINGS_EDITOR_COMMAND_FILTER_MODIFIED, SETTINGS_EDITOR_COMMAND_FILTER_ONLINE, SETTINGS_EDITOR_COMMAND_FOCUS_FILE, SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH, SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST, SETTINGS_EDITOR_COMMAND_SEARCH, SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU, SETTINGS_EDITOR_COMMAND_SWITCH_TO_JSON, SETTINGS_COMMAND_OPEN_SETTINGS, KEYBINDINGS_EDITOR_COMMAND_DEFINE_WHEN } from 'vs/workbench/contrib/preferences/common/preferences';
import { PreferencesContribution } from 'vs/workbench/contrib/preferences/common/preferencesContribution';
import { SettingsEditor2 } from 'vs/workbench/contrib/preferences/browser/settingsEditor2';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import { DefaultPreferencesEditorInput, KeybindingsEditorInput, PreferencesEditorInput, SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput';
import { ExplorerRootContext, ExplorerFolderContext } from 'vs/workbench/contrib/files/common/files';
import { ILabelService } from 'vs/platform/label/common/label';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
new EditorDescriptor(
PreferencesEditor,
PreferencesEditor.ID,
nls.localize('defaultPreferencesEditor', "Default Preferences Editor")
),
[
new SyncDescriptor(PreferencesEditorInput)
]
);
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
new EditorDescriptor(
SettingsEditor2,
SettingsEditor2.ID,
nls.localize('settingsEditor2', "Settings Editor 2")
),
[
new SyncDescriptor(SettingsEditor2Input)
]
);
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
new EditorDescriptor(
KeybindingsEditor,
KeybindingsEditor.ID,
nls.localize('keybindingsEditor', "Keybindings Editor")
),
[
new SyncDescriptor(KeybindingsEditorInput)
]
);
interface ISerializedPreferencesEditorInput {
name: string;
description: string;
detailsSerialized: string;
masterSerialized: string;
detailsTypeId: string;
masterTypeId: string;
}
// Register Preferences Editor Input Factory
class PreferencesEditorInputFactory implements IEditorInputFactory {
serialize(editorInput: EditorInput): string | undefined {
const input = <PreferencesEditorInput>editorInput;
if (input.details && input.master) {
const registry = Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories);
const detailsInputFactory = registry.getEditorInputFactory(input.details.getTypeId());
const masterInputFactory = registry.getEditorInputFactory(input.master.getTypeId());
if (detailsInputFactory && masterInputFactory) {
const detailsSerialized = detailsInputFactory.serialize(input.details);
const masterSerialized = masterInputFactory.serialize(input.master);
if (detailsSerialized && masterSerialized) {
return JSON.stringify(<ISerializedPreferencesEditorInput>{
name: input.getName(),
description: input.getDescription(),
detailsSerialized,
masterSerialized,
detailsTypeId: input.details.getTypeId(),
masterTypeId: input.master.getTypeId()
});
}
}
}
return undefined;
}
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput | undefined {
const deserialized: ISerializedPreferencesEditorInput = JSON.parse(serializedEditorInput);
const registry = Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories);
const detailsInputFactory = registry.getEditorInputFactory(deserialized.detailsTypeId);
const masterInputFactory = registry.getEditorInputFactory(deserialized.masterTypeId);
if (detailsInputFactory && masterInputFactory) {
const detailsInput = detailsInputFactory.deserialize(instantiationService, deserialized.detailsSerialized);
const masterInput = masterInputFactory.deserialize(instantiationService, deserialized.masterSerialized);
if (detailsInput && masterInput) {
return new PreferencesEditorInput(deserialized.name, deserialized.description, detailsInput, masterInput);
}
}
return undefined;
}
}
class KeybindingsEditorInputFactory implements IEditorInputFactory {
serialize(editorInput: EditorInput): string {
const input = <KeybindingsEditorInput>editorInput;
return JSON.stringify({
name: input.getName(),
typeId: input.getTypeId()
});
}
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
return instantiationService.createInstance(KeybindingsEditorInput);
}
}
interface ISerializedSettingsEditor2EditorInput {
}
class SettingsEditor2InputFactory implements IEditorInputFactory {
serialize(input: SettingsEditor2Input): string {
const serialized: ISerializedSettingsEditor2EditorInput = {
};
return JSON.stringify(serialized);
}
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): SettingsEditor2Input {
return instantiationService.createInstance(
SettingsEditor2Input);
}
}
interface ISerializedDefaultPreferencesEditorInput {
resource: string;
}
// Register Default Preferences Editor Input Factory
class DefaultPreferencesEditorInputFactory implements IEditorInputFactory {
serialize(editorInput: EditorInput): string {
const input = <DefaultPreferencesEditorInput>editorInput;
const serialized: ISerializedDefaultPreferencesEditorInput = { resource: input.getResource().toString() };
return JSON.stringify(serialized);
}
deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
const deserialized: ISerializedDefaultPreferencesEditorInput = JSON.parse(serializedEditorInput);
return instantiationService.createInstance(DefaultPreferencesEditorInput, URI.parse(deserialized.resource));
}
}
Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories).registerEditorInputFactory(PreferencesEditorInput.ID, PreferencesEditorInputFactory);
Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories).registerEditorInputFactory(DefaultPreferencesEditorInput.ID, DefaultPreferencesEditorInputFactory);
Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories).registerEditorInputFactory(KeybindingsEditorInput.ID, KeybindingsEditorInputFactory);
Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories).registerEditorInputFactory(SettingsEditor2Input.ID, SettingsEditor2InputFactory);
// Contribute Global Actions
const category = nls.localize('preferences', "Preferences");
const registry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenRawDefaultSettingsAction, OpenRawDefaultSettingsAction.ID, OpenRawDefaultSettingsAction.LABEL), 'Preferences: Open Default Settings (JSON)', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettingsJsonAction, OpenSettingsJsonAction.ID, OpenSettingsJsonAction.LABEL), 'Preferences: Open Settings (JSON)', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenSettings2Action, OpenSettings2Action.ID, OpenSettings2Action.LABEL), 'Preferences: Open Settings (UI)', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalSettingsAction, OpenGlobalSettingsAction.ID, OpenGlobalSettingsAction.LABEL), 'Preferences: Open User Settings', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalKeybindingsAction, OpenGlobalKeybindingsAction.ID, OpenGlobalKeybindingsAction.LABEL, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_S) }), 'Preferences: Open Keyboard Shortcuts', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenDefaultKeybindingsFileAction, OpenDefaultKeybindingsFileAction.ID, OpenDefaultKeybindingsFileAction.LABEL), 'Preferences: Open Default Keyboard Shortcuts (JSON)', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(OpenGlobalKeybindingsFileAction, OpenGlobalKeybindingsFileAction.ID, OpenGlobalKeybindingsFileAction.LABEL, { primary: 0 }), 'Preferences: Open Keyboard Shortcuts (JSON)', category);
registry.registerWorkbenchAction(new SyncActionDescriptor(ConfigureLanguageBasedSettingsAction, ConfigureLanguageBasedSettingsAction.ID, ConfigureLanguageBasedSettingsAction.LABEL), 'Preferences: Configure Language Specific Settings...', category);
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: SETTINGS_COMMAND_OPEN_SETTINGS,
weight: KeybindingWeight.WorkbenchContrib,
when: null,
primary: KeyMod.CtrlCmd | KeyCode.US_COMMA,
handler: (accessor, args: string | undefined) => {
accessor.get(IPreferencesService).openSettings(undefined, typeof args === 'string' ? args : undefined);
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_DEFINE,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDING_FOCUS),
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_K),
handler: (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control && control instanceof KeybindingsEditor) {
control.defineKeybinding(control.activeKeybindingEntry!);
}
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_DEFINE_WHEN,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDING_FOCUS),
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_E),
handler: (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control && control instanceof KeybindingsEditor && control.activeKeybindingEntry!.keybindingItem.keybinding) {
control.defineWhenExpression(control.activeKeybindingEntry!);
}
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_REMOVE,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDING_FOCUS),
primary: KeyCode.Delete,
mac: {
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.Backspace)
},
handler: (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control && control instanceof KeybindingsEditor) {
control.removeKeybinding(control.activeKeybindingEntry!);
}
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_RESET,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDING_FOCUS),
primary: 0,
handler: (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control && control instanceof KeybindingsEditor) {
control.resetKeybinding(control.activeKeybindingEntry!);
}
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_SEARCH,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR),
primary: KeyMod.CtrlCmd | KeyCode.KEY_F,
handler: (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control && control instanceof KeybindingsEditor) {
control.focusSearch();
}
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_RECORD_SEARCH_KEYS,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDINGS_SEARCH_FOCUS),
primary: KeyMod.Alt | KeyCode.KEY_K,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_K },
handler: (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control && control instanceof KeybindingsEditor) {
control.recordSearchKeys();
}
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_SORTBY_PRECEDENCE,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR),
primary: KeyMod.Alt | KeyCode.KEY_P,
mac: { primary: KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.KEY_P },
handler: (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control && control instanceof KeybindingsEditor) {
control.toggleSortByPrecedence();
}
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_SHOW_SIMILAR,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDING_FOCUS),
primary: 0,
handler: (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control) {
control.showSimilarKeybindings(control.activeKeybindingEntry!);
}
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_COPY,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDING_FOCUS),
primary: KeyMod.CtrlCmd | KeyCode.KEY_C,
handler: async (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control) {
await control.copyKeybinding(control.activeKeybindingEntry!);
}
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_COPY_COMMAND,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDING_FOCUS),
primary: 0,
handler: async (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control) {
await control.copyKeybindingCommand(control.activeKeybindingEntry!);
}
}
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_FOCUS_KEYBINDINGS,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDINGS_SEARCH_FOCUS),
primary: KeyCode.DownArrow,
handler: (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control) {
control.focusKeybindings();
}
}
});
class PreferencesActionsContribution extends Disposable implements IWorkbenchContribution {
constructor(
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@IPreferencesService private readonly preferencesService: IPreferencesService,
@IWorkspaceContextService private readonly workpsaceContextService: IWorkspaceContextService,
@ILabelService labelService: ILabelService,
@IExtensionService extensionService: IExtensionService,
) {
super();
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: OpenGlobalKeybindingsAction.ID,
title: OpenGlobalKeybindingsAction.LABEL,
iconLocation: {
light: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-light.svg`)),
dark: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-dark.svg`))
}
},
when: ResourceContextKey.Resource.isEqualTo(environmentService.keybindingsResource.toString()),
group: 'navigation',
order: 1
});
const commandId = '_workbench.openUserSettingsEditor';
CommandsRegistry.registerCommand(commandId, () => this.preferencesService.openGlobalSettings(false));
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: commandId,
title: OpenSettings2Action.LABEL,
iconLocation: {
light: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-light.svg`)),
dark: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-dark.svg`))
}
},
when: ResourceContextKey.Resource.isEqualTo(environmentService.settingsResource.toString()),
group: 'navigation',
order: 1
});
this.updatePreferencesEditorMenuItem();
this._register(workpsaceContextService.onDidChangeWorkbenchState(() => this.updatePreferencesEditorMenuItem()));
this._register(workpsaceContextService.onDidChangeWorkspaceFolders(() => this.updatePreferencesEditorMenuItemForWorkspaceFolders()));
extensionService.whenInstalledExtensionsRegistered()
.then(() => {
const remoteAuthority = environmentService.configuration.remoteAuthority;
const hostLabel = labelService.getHostLabel(REMOTE_HOST_SCHEME, remoteAuthority) || remoteAuthority;
const label = nls.localize('openRemoteSettings', "Open Remote Settings ({0})", hostLabel);
CommandsRegistry.registerCommand(OpenRemoteSettingsAction.ID, serviceAccessor => {
serviceAccessor.get(IInstantiationService).createInstance(OpenRemoteSettingsAction, OpenRemoteSettingsAction.ID, label).run();
});
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
command: {
id: OpenRemoteSettingsAction.ID,
title: { value: label, original: `Open Remote Settings (${hostLabel})` },
category: { value: nls.localize('preferencesCategory', "Preferences"), original: 'Preferences' }
},
when: RemoteAuthorityContext.notEqualsTo('')
});
});
}
private updatePreferencesEditorMenuItem() {
const commandId = '_workbench.openWorkspaceSettingsEditor';
if (this.workpsaceContextService.getWorkbenchState() === WorkbenchState.WORKSPACE && !CommandsRegistry.getCommand(commandId)) {
CommandsRegistry.registerCommand(commandId, () => this.preferencesService.openWorkspaceSettings(false));
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: commandId,
title: OpenSettings2Action.LABEL,
iconLocation: {
light: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-light.svg`)),
dark: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-dark.svg`))
}
},
when: ContextKeyExpr.and(ResourceContextKey.Resource.isEqualTo(this.preferencesService.workspaceSettingsResource!.toString()), WorkbenchStateContext.isEqualTo('workspace')),
group: 'navigation',
order: 1
});
}
this.updatePreferencesEditorMenuItemForWorkspaceFolders();
}
private updatePreferencesEditorMenuItemForWorkspaceFolders() {
for (const folder of this.workpsaceContextService.getWorkspace().folders) {
const commandId = `_workbench.openFolderSettings.${folder.uri.toString()}`;
if (!CommandsRegistry.getCommand(commandId)) {
CommandsRegistry.registerCommand(commandId, () => {
if (this.workpsaceContextService.getWorkbenchState() === WorkbenchState.FOLDER) {
return this.preferencesService.openWorkspaceSettings(false);
} else {
return this.preferencesService.openFolderSettings(folder.uri, false);
}
});
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: commandId,
title: OpenSettings2Action.LABEL,
iconLocation: {
light: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-light.svg`)),
dark: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-dark.svg`))
}
},
when: ContextKeyExpr.and(ResourceContextKey.Resource.isEqualTo(this.preferencesService.getFolderSettingsResource(folder.uri)!.toString())),
group: 'navigation',
order: 1
});
}
}
}
}
const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
workbenchContributionsRegistry.registerWorkbenchContribution(PreferencesActionsContribution, LifecyclePhase.Starting);
workbenchContributionsRegistry.registerWorkbenchContribution(PreferencesContribution, LifecyclePhase.Starting);
CommandsRegistry.registerCommand(OPEN_FOLDER_SETTINGS_COMMAND, function (accessor: ServicesAccessor, resource: URI) {
const preferencesService = accessor.get(IPreferencesService);
return preferencesService.openFolderSettings(resource);
});
CommandsRegistry.registerCommand(OpenFolderSettingsAction.ID, serviceAccessor => {
serviceAccessor.get(IInstantiationService).createInstance(OpenFolderSettingsAction, OpenFolderSettingsAction.ID, OpenFolderSettingsAction.LABEL).run();
});
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
command: {
id: OpenFolderSettingsAction.ID,
title: { value: OpenFolderSettingsAction.LABEL, original: 'Open Folder Settings' },
category: { value: nls.localize('preferencesCategory', "Preferences"), original: 'Preferences' }
},
when: WorkbenchStateContext.isEqualTo('workspace')
});
CommandsRegistry.registerCommand(OpenWorkspaceSettingsAction.ID, serviceAccessor => {
serviceAccessor.get(IInstantiationService).createInstance(OpenWorkspaceSettingsAction, OpenWorkspaceSettingsAction.ID, OpenWorkspaceSettingsAction.LABEL).run();
});
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
command: {
id: OpenWorkspaceSettingsAction.ID,
title: { value: OpenWorkspaceSettingsAction.LABEL, original: 'Open Workspace Settings' },
category: { value: nls.localize('preferencesCategory', "Preferences"), original: 'Preferences' }
},
when: WorkbenchStateContext.notEqualsTo('empty')
});
KeybindingsRegistry.registerCommandAndKeybindingRule({
id: KEYBINDINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR, CONTEXT_KEYBINDINGS_SEARCH_FOCUS),
primary: KeyCode.Escape,
handler: (accessor, args: any) => {
const control = accessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control) {
control.clearSearchResults();
}
}
});
CommandsRegistry.registerCommand(OpenGlobalKeybindingsFileAction.ID, serviceAccessor => {
serviceAccessor.get(IInstantiationService).createInstance(OpenGlobalKeybindingsFileAction, OpenGlobalKeybindingsFileAction.ID, OpenGlobalKeybindingsFileAction.LABEL).run();
});
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: OpenGlobalKeybindingsFileAction.ID,
title: OpenGlobalKeybindingsFileAction.LABEL,
iconLocation: {
light: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/edit-json-light.svg`)),
dark: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/edit-json-dark.svg`))
}
},
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR),
group: 'navigation',
});
CommandsRegistry.registerCommand(KEYBINDINGS_EDITOR_SHOW_DEFAULT_KEYBINDINGS, serviceAccessor => {
const control = serviceAccessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control) {
control.search('@source:default');
}
});
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: KEYBINDINGS_EDITOR_SHOW_DEFAULT_KEYBINDINGS,
title: nls.localize('showDefaultKeybindings', "Show Default Keybindings")
},
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR),
group: '1_keyboard_preferences_actions'
});
CommandsRegistry.registerCommand(KEYBINDINGS_EDITOR_SHOW_USER_KEYBINDINGS, serviceAccessor => {
const control = serviceAccessor.get(IEditorService).activeControl as IKeybindingsEditor;
if (control) {
control.search('@source:user');
}
});
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: KEYBINDINGS_EDITOR_SHOW_USER_KEYBINDINGS,
title: nls.localize('showUserKeybindings', "Show User Keybindings")
},
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR),
group: '1_keyboard_preferences_actions'
});
abstract class SettingsCommand extends Command {
protected getPreferencesEditor(accessor: ServicesAccessor): PreferencesEditor | SettingsEditor2 | null {
const activeControl = accessor.get(IEditorService).activeControl;
if (activeControl instanceof PreferencesEditor || activeControl instanceof SettingsEditor2) {
return activeControl;
}
return null;
}
}
class StartSearchDefaultSettingsCommand extends SettingsCommand {
runCommand(accessor: ServicesAccessor, args: any): void {
const preferencesEditor = this.getPreferencesEditor(accessor);
if (preferencesEditor) {
preferencesEditor.focusSearch();
}
}
}
const startSearchCommand = new StartSearchDefaultSettingsCommand({
id: SETTINGS_EDITOR_COMMAND_SEARCH,
precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR),
kbOpts: { primary: KeyMod.CtrlCmd | KeyCode.KEY_F, weight: KeybindingWeight.EditorContrib }
});
startSearchCommand.register();
class ClearSearchResultsCommand extends SettingsCommand {
runCommand(accessor: ServicesAccessor, args: any): void {
const preferencesEditor = this.getPreferencesEditor(accessor);
if (preferencesEditor) {
preferencesEditor.clearSearchResults();
}
}
}
const clearSearchResultsCommand = new ClearSearchResultsCommand({
id: SETTINGS_EDITOR_COMMAND_CLEAR_SEARCH_RESULTS,
precondition: CONTEXT_SETTINGS_SEARCH_FOCUS,
kbOpts: { primary: KeyCode.Escape, weight: KeybindingWeight.EditorContrib }
});
clearSearchResultsCommand.register();
class FocusSettingsFileEditorCommand extends SettingsCommand {
runCommand(accessor: ServicesAccessor, args: any): void {
const preferencesEditor = this.getPreferencesEditor(accessor);
if (preferencesEditor instanceof PreferencesEditor) {
preferencesEditor.focusSettingsFileEditor();
} else if (preferencesEditor) {
preferencesEditor.focusSettings();
}
}
}
const focusSettingsFileEditorCommand = new FocusSettingsFileEditorCommand({
id: SETTINGS_EDITOR_COMMAND_FOCUS_FILE,
precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_SEARCH_FOCUS, SuggestContext.Visible.toNegated()),
kbOpts: { primary: KeyCode.DownArrow, weight: KeybindingWeight.EditorContrib }
});
focusSettingsFileEditorCommand.register();
const focusSettingsFromSearchCommand = new FocusSettingsFileEditorCommand({
id: SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH,
precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_SEARCH_FOCUS, SuggestContext.Visible.toNegated()),
kbOpts: { primary: KeyCode.DownArrow, weight: KeybindingWeight.WorkbenchContrib }
});
focusSettingsFromSearchCommand.register();
class FocusNextSearchResultCommand extends SettingsCommand {
runCommand(accessor: ServicesAccessor, args: any): void {
const preferencesEditor = this.getPreferencesEditor(accessor);
if (preferencesEditor instanceof PreferencesEditor) {
preferencesEditor.focusNextResult();
}
}
}
const focusNextSearchResultCommand = new FocusNextSearchResultCommand({
id: SETTINGS_EDITOR_COMMAND_FOCUS_NEXT_SETTING,
precondition: CONTEXT_SETTINGS_SEARCH_FOCUS,
kbOpts: { primary: KeyCode.Enter, weight: KeybindingWeight.EditorContrib }
});
focusNextSearchResultCommand.register();
class FocusPreviousSearchResultCommand extends SettingsCommand {
runCommand(accessor: ServicesAccessor, args: any): void {
const preferencesEditor = this.getPreferencesEditor(accessor);
if (preferencesEditor instanceof PreferencesEditor) {
preferencesEditor.focusPreviousResult();
}
}
}
const focusPreviousSearchResultCommand = new FocusPreviousSearchResultCommand({
id: SETTINGS_EDITOR_COMMAND_FOCUS_PREVIOUS_SETTING,
precondition: CONTEXT_SETTINGS_SEARCH_FOCUS,
kbOpts: { primary: KeyMod.Shift | KeyCode.Enter, weight: KeybindingWeight.EditorContrib }
});
focusPreviousSearchResultCommand.register();
class EditFocusedSettingCommand extends SettingsCommand {
runCommand(accessor: ServicesAccessor, args: any): void {
const preferencesEditor = this.getPreferencesEditor(accessor);
if (preferencesEditor instanceof PreferencesEditor) {
preferencesEditor.editFocusedPreference();
}
}
}
const editFocusedSettingCommand = new EditFocusedSettingCommand({
id: SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING,
precondition: CONTEXT_SETTINGS_SEARCH_FOCUS,
kbOpts: { primary: KeyMod.CtrlCmd | KeyCode.US_DOT, weight: KeybindingWeight.EditorContrib }
});
editFocusedSettingCommand.register();
class FocusSettingsListCommand extends SettingsCommand {
runCommand(accessor: ServicesAccessor, args: any): void {
const preferencesEditor = this.getPreferencesEditor(accessor);
if (preferencesEditor instanceof SettingsEditor2) {
preferencesEditor.focusSettings();
}
}
}
const focusSettingsListCommand = new FocusSettingsListCommand({
id: SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST,
precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR, CONTEXT_TOC_ROW_FOCUS),
kbOpts: { primary: KeyCode.Enter, weight: KeybindingWeight.WorkbenchContrib }
});
focusSettingsListCommand.register();
class ShowContextMenuCommand extends SettingsCommand {
runCommand(accessor: ServicesAccessor, args: any): void {
const preferencesEditor = this.getPreferencesEditor(accessor);
if (preferencesEditor instanceof SettingsEditor2) {
preferencesEditor.showContextMenu();
}
}
}
const showContextMenuCommand = new ShowContextMenuCommand({
id: SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU,
precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR),
kbOpts: { primary: KeyMod.Shift | KeyCode.F9, weight: KeybindingWeight.WorkbenchContrib }
});
showContextMenuCommand.register();
CommandsRegistry.registerCommand(SETTINGS_EDITOR_COMMAND_SWITCH_TO_JSON, serviceAccessor => {
const control = serviceAccessor.get(IEditorService).activeControl as SettingsEditor2;
if (control instanceof SettingsEditor2) {
return control.switchToSettingsFile();
}
return Promise.resolve(null);
});
CommandsRegistry.registerCommand(SETTINGS_EDITOR_COMMAND_FILTER_MODIFIED, serviceAccessor => {
const control = serviceAccessor.get(IEditorService).activeControl as SettingsEditor2;
if (control instanceof SettingsEditor2) {
control.focusSearch(`@${MODIFIED_SETTING_TAG}`);
}
});
CommandsRegistry.registerCommand(SETTINGS_EDITOR_COMMAND_FILTER_ONLINE, serviceAccessor => {
const control = serviceAccessor.get(IEditorService).activeControl as SettingsEditor2;
if (control instanceof SettingsEditor2) {
control.focusSearch(`@tag:usesOnlineServices`);
} else {
serviceAccessor.get(IPreferencesService).openSettings(false, '@tag:usesOnlineServices');
}
});
// Preferences menu
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
title: nls.localize({ key: 'miPreferences', comment: ['&& denotes a mnemonic'] }, "&&Preferences"),
submenu: MenuId.MenubarPreferencesMenu,
group: '5_autosave',
order: 2,
when: IsMacNativeContext.toNegated() // on macOS native the preferences menu is separate under the application menu
});
MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, {
group: '1_settings',
command: {
id: SETTINGS_COMMAND_OPEN_SETTINGS,
title: nls.localize({ key: 'miOpenSettings', comment: ['&& denotes a mnemonic'] }, "&&Settings")
},
order: 1
});
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
group: '2_configuration',
command: {
id: SETTINGS_COMMAND_OPEN_SETTINGS,
title: nls.localize('settings', "Settings")
},
order: 1
});
MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, {
group: '1_settings',
command: {
id: SETTINGS_EDITOR_COMMAND_FILTER_ONLINE,
title: nls.localize({ key: 'miOpenOnlineSettings', comment: ['&& denotes a mnemonic'] }, "&&Online Services Settings")
},
order: 2
});
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
group: '2_configuration',
command: {
id: SETTINGS_EDITOR_COMMAND_FILTER_ONLINE,
title: nls.localize('onlineServices', "Online Services Settings")
},
order: 2
});
MenuRegistry.appendMenuItem(MenuId.MenubarPreferencesMenu, {
group: '2_keybindings',
command: {
id: OpenGlobalKeybindingsAction.ID,
title: nls.localize({ key: 'miOpenKeymap', comment: ['&& denotes a mnemonic'] }, "&&Keyboard Shortcuts")
},
order: 1
});
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
group: '2_keybindings',
command: {
id: OpenGlobalKeybindingsAction.ID,
title: nls.localize('keyboardShortcuts', "Keyboard Shortcuts")
},
order: 1
});
// Editor tool items
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: SETTINGS_EDITOR_COMMAND_SWITCH_TO_JSON,
title: nls.localize('openSettingsJson', "Open Settings (JSON)"),
iconLocation: {
dark: URI.parse(require.toUrl('vs/workbench/contrib/preferences/browser/media/edit-json-dark.svg')),
light: URI.parse(require.toUrl('vs/workbench/contrib/preferences/browser/media/edit-json-light.svg'))
}
},
group: 'navigation',
order: 1,
when: ContextKeyExpr.and(
CONTEXT_SETTINGS_EDITOR,
CONTEXT_SETTINGS_JSON_EDITOR.toNegated()
)
});
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: SETTINGS_EDITOR_COMMAND_FILTER_MODIFIED,
title: nls.localize('filterModifiedLabel', "Show modified settings")
},
group: '1_filter',
order: 1,
when: ContextKeyExpr.and(
CONTEXT_SETTINGS_EDITOR,
CONTEXT_SETTINGS_JSON_EDITOR.toNegated()
)
});
MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
command: {
id: SETTINGS_EDITOR_COMMAND_FILTER_ONLINE,
title: nls.localize('filterOnlineServicesLabel', "Show settings for online services"),
},
group: '1_filter',
order: 2,
when: ContextKeyExpr.and(
CONTEXT_SETTINGS_EDITOR,
CONTEXT_SETTINGS_JSON_EDITOR.toNegated()
)
});
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
group: '2_workspace',
order: 20,
command: {
id: OPEN_FOLDER_SETTINGS_COMMAND,
title: OPEN_FOLDER_SETTINGS_LABEL
},
when: ContextKeyExpr.and(ExplorerRootContext, ExplorerFolderContext)
});

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Action } from 'vs/base/common/actions';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { dispose, IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { getIconClasses } from 'vs/editor/common/services/getIconClasses';
import { IModelService } from 'vs/editor/common/services/modelService';
@@ -164,7 +164,7 @@ export class OpenWorkspaceSettingsAction extends Action {
static readonly ID = 'workbench.action.openWorkspaceSettings';
static readonly LABEL = nls.localize('openWorkspaceSettings', "Open Workspace Settings");
private disposables: IDisposable[] = [];
private readonly disposables = new DisposableStore();
constructor(
id: string,
@@ -174,7 +174,7 @@ export class OpenWorkspaceSettingsAction extends Action {
) {
super(id, label);
this.update();
this.workspaceContextService.onDidChangeWorkbenchState(() => this.update(), this, this.disposables);
this.disposables.add(this.workspaceContextService.onDidChangeWorkbenchState(() => this.update(), this));
}
private update(): void {
@@ -186,7 +186,7 @@ export class OpenWorkspaceSettingsAction extends Action {
}
dispose(): void {
this.disposables = dispose(this.disposables);
this.disposables.dispose();
super.dispose();
}
}

View File

@@ -31,7 +31,7 @@ import { ConfigurationTarget } from 'vs/platform/configuration/common/configurat
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ILogService } from 'vs/platform/log/common/log';
import { IProgressService } from 'vs/platform/progress/common/progress';
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
import { Registry } from 'vs/platform/registry/common/platform';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@@ -84,7 +84,7 @@ export class PreferencesEditor extends BaseEditor {
readonly minimumHeight = 260;
private _onDidCreateWidget = new Emitter<{ width: number; height: number; } | undefined>();
private _onDidCreateWidget = this._register(new Emitter<{ width: number; height: number; } | undefined>());
readonly onDidSizeConstraintsChange: Event<{ width: number; height: number; } | undefined> = this._onDidCreateWidget.event;
constructor(
@@ -94,7 +94,7 @@ export class PreferencesEditor extends BaseEditor {
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@IProgressService private readonly progressService: IProgressService,
@IEditorProgressService private readonly editorProgressService: IEditorProgressService,
@IStorageService storageService: IStorageService
) {
super(PreferencesEditor.ID, telemetryService, themeService, storageService);
@@ -237,7 +237,7 @@ export class PreferencesEditor extends BaseEditor {
if (query) {
return Promise.all([
this.localSearchDelayer.trigger(() => this.preferencesRenderers.localFilterPreferences(query).then(() => { })),
this.remoteSearchThrottle.trigger(() => Promise.resolve(this.progressService.showWhile(this.preferencesRenderers.remoteSearchPreferences(query), 500)))
this.remoteSearchThrottle.trigger(() => Promise.resolve(this.editorProgressService.showWhile(this.preferencesRenderers.remoteSearchPreferences(query), 500)))
]).then(() => { });
} else {
// When clearing the input, update immediately to clear it
@@ -284,7 +284,7 @@ export class PreferencesEditor extends BaseEditor {
}
private _countById(settingsGroups: ISettingsGroup[]): IStringDictionary<number> {
const result = {};
const result: IStringDictionary<number> = {};
for (const group of settingsGroups) {
let i = 0;
@@ -330,11 +330,6 @@ export class PreferencesEditor extends BaseEditor {
this._lastReportedFilter = filter;
}
}
dispose(): void {
this._onDidCreateWidget.dispose();
super.dispose();
}
}
class SettingsNavigator extends ArrayNavigator<ISetting> {
@@ -685,7 +680,7 @@ class PreferencesRenderersController extends Disposable {
}
private _updatePreference(key: string, value: any, source: ISetting, fromEditableSettings?: boolean): void {
const data = {
const data: { [key: string]: any } = {
userConfigurationKeys: [key]
};
@@ -774,10 +769,10 @@ class SideBySidePreferencesWidget extends Widget {
private settingsTargetsWidget: SettingsTargetsWidget;
private readonly _onFocus = new Emitter<void>();
private readonly _onFocus = this._register(new Emitter<void>());
readonly onFocus: Event<void> = this._onFocus.event;
private readonly _onDidSettingsTargetChange = new Emitter<SettingsTarget>();
private readonly _onDidSettingsTargetChange = this._register(new Emitter<SettingsTarget>());
readonly onDidSettingsTargetChange: Event<SettingsTarget> = this._onDidSettingsTargetChange.event;
private splitview: SplitView;

View File

@@ -4,12 +4,12 @@
*--------------------------------------------------------------------------------------------*/
import { ContextSubMenu } from 'vs/base/browser/contextmenu';
import { getDomNodePagePosition } from 'vs/base/browser/dom';
import { EventHelper, getDomNodePagePosition } from 'vs/base/browser/dom';
import { IAction } from 'vs/base/common/actions';
import { Delayer } from 'vs/base/common/async';
import { Emitter, Event } from 'vs/base/common/event';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { Position } from 'vs/editor/common/core/position';
@@ -56,13 +56,13 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend
private modelChangeDelayer: Delayer<void> = new Delayer<void>(200);
private associatedPreferencesModel: IPreferencesEditorModel<ISetting>;
private readonly _onFocusPreference = new Emitter<ISetting>();
private readonly _onFocusPreference = this._register(new Emitter<ISetting>());
readonly onFocusPreference: Event<ISetting> = this._onFocusPreference.event;
private readonly _onClearFocusPreference = new Emitter<ISetting>();
private readonly _onClearFocusPreference = this._register(new Emitter<ISetting>());
readonly onClearFocusPreference: Event<ISetting> = this._onClearFocusPreference.event;
private readonly _onUpdatePreference: Emitter<{ key: string, value: any, source: IIndexedSetting }> = new Emitter<{ key: string, value: any, source: IIndexedSetting }>();
private readonly _onUpdatePreference = this._register(new Emitter<{ key: string, value: any, source: IIndexedSetting }>());
readonly onUpdatePreference: Event<{ key: string, value: any, source: IIndexedSetting }> = this._onUpdatePreference.event;
private filterResult: IFilterResult | undefined;
@@ -233,13 +233,13 @@ export class DefaultSettingsRenderer extends Disposable implements IPreferencesR
private bracesHidingRenderer: BracesHidingRenderer;
private filterResult: IFilterResult | undefined;
private readonly _onUpdatePreference: Emitter<{ key: string, value: any, source: IIndexedSetting }> = new Emitter<{ key: string, value: any, source: IIndexedSetting }>();
private readonly _onUpdatePreference = this._register(new Emitter<{ key: string, value: any, source: IIndexedSetting }>());
readonly onUpdatePreference: Event<{ key: string, value: any, source: IIndexedSetting }> = this._onUpdatePreference.event;
private readonly _onFocusPreference = new Emitter<ISetting>();
private readonly _onFocusPreference = this._register(new Emitter<ISetting>());
readonly onFocusPreference: Event<ISetting> = this._onFocusPreference.event;
private readonly _onClearFocusPreference = new Emitter<ISetting>();
private readonly _onClearFocusPreference = this._register(new Emitter<ISetting>());
readonly onClearFocusPreference: Event<ISetting> = this._onClearFocusPreference.event;
constructor(protected editor: ICodeEditor, readonly preferencesModel: DefaultSettingsEditorModel,
@@ -436,13 +436,13 @@ class DefaultSettingsHeaderRenderer extends Disposable {
export class SettingsGroupTitleRenderer extends Disposable implements HiddenAreasProvider {
private readonly _onHiddenAreasChanged = new Emitter<void>();
get onHiddenAreasChanged(): Event<void> { return this._onHiddenAreasChanged.event; }
private readonly _onHiddenAreasChanged = this._register(new Emitter<void>());
readonly onHiddenAreasChanged: Event<void> = this._onHiddenAreasChanged.event;
private settingsGroups: ISettingsGroup[];
private hiddenGroups: ISettingsGroup[] = [];
private settingsGroupTitleWidgets: SettingsGroupTitleWidget[];
private disposables: IDisposable[] = [];
private readonly renderDisposables = this._register(new DisposableStore());
constructor(private editor: ICodeEditor,
@IInstantiationService private readonly instantiationService: IInstantiationService
@@ -474,8 +474,8 @@ export class SettingsGroupTitleRenderer extends Disposable implements HiddenArea
const settingsGroupTitleWidget = this.instantiationService.createInstance(SettingsGroupTitleWidget, this.editor, group);
settingsGroupTitleWidget.render();
this.settingsGroupTitleWidgets.push(settingsGroupTitleWidget);
this.disposables.push(settingsGroupTitleWidget);
this.disposables.push(settingsGroupTitleWidget.onToggled(collapsed => this.onToggled(collapsed, settingsGroupTitleWidget.settingsGroup)));
this.renderDisposables.add(settingsGroupTitleWidget);
this.renderDisposables.add(settingsGroupTitleWidget.onToggled(collapsed => this.onToggled(collapsed, settingsGroupTitleWidget.settingsGroup)));
}
this.settingsGroupTitleWidgets.reverse();
}
@@ -515,7 +515,7 @@ export class SettingsGroupTitleRenderer extends Disposable implements HiddenArea
private disposeWidgets() {
this.hiddenGroups = [];
this.disposables = dispose(this.disposables);
this.renderDisposables.clear();
}
dispose() {
@@ -820,6 +820,8 @@ class EditSettingRenderer extends Disposable {
}
private onEditSettingClicked(editPreferenceWidget: EditPreferenceWidget<IIndexedSetting>, e: IEditorMouseEvent): void {
EventHelper.stop(e.event, true);
const anchor = { x: e.event.posx, y: e.event.posy + 10 };
const actions = this.getSettings(editPreferenceWidget.getLine()).length === 1 ? this.getActions(editPreferenceWidget.preferences[0], this.getConfigurationsMap()[editPreferenceWidget.preferences[0].key])
: editPreferenceWidget.preferences.map(setting => new ContextSubMenu(setting.key, this.getActions(setting, this.getConfigurationsMap()[setting.key])));
@@ -916,8 +918,8 @@ class SettingHighlighter extends Disposable {
super();
this.fixedHighlighter = this._register(instantiationService.createInstance(RangeHighlightDecorations));
this.volatileHighlighter = this._register(instantiationService.createInstance(RangeHighlightDecorations));
this.fixedHighlighter.onHighlghtRemoved(() => this.clearFocusEventEmitter.fire(this.highlightedSetting));
this.volatileHighlighter.onHighlghtRemoved(() => this.clearFocusEventEmitter.fire(this.highlightedSetting));
this.fixedHighlighter.onHighlightRemoved(() => this.clearFocusEventEmitter.fire(this.highlightedSetting));
this.volatileHighlighter.onHighlightRemoved(() => this.clearFocusEventEmitter.fire(this.highlightedSetting));
}
highlight(setting: ISetting, fix: boolean = false) {

View File

@@ -0,0 +1,565 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ISettingsEditorModel, ISetting, ISettingsGroup, IFilterMetadata, ISearchResult, IGroupFilter, ISettingMatcher, IScoredResults, ISettingMatch, IRemoteSetting, IExtensionSetting } from 'vs/workbench/services/preferences/common/preferences';
import { IRange } from 'vs/editor/common/core/range';
import { distinct, top } from 'vs/base/common/arrays';
import * as strings from 'vs/base/common/strings';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
import { IMatch, or, matchesContiguousSubString, matchesPrefix, matchesCamelCase, matchesWords } from 'vs/base/common/filters';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { Disposable } from 'vs/base/common/lifecycle';
import { IPreferencesSearchService, ISearchProvider, IWorkbenchSettingsConfiguration } from 'vs/workbench/contrib/preferences/common/preferences';
import { IRequestService, asJson } from 'vs/platform/request/common/request';
import { IExtensionManagementService, ILocalExtension, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ILogService } from 'vs/platform/log/common/log';
import { CancellationToken } from 'vs/base/common/cancellation';
import { canceled } from 'vs/base/common/errors';
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
import { nullRange } from 'vs/workbench/services/preferences/common/preferencesModels';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IStringDictionary } from 'vs/base/common/collections';
import { IProductService } from 'vs/platform/product/common/product';
export interface IEndpointDetails {
urlBase?: string;
key?: string;
}
export class PreferencesSearchService extends Disposable implements IPreferencesSearchService {
_serviceBrand: any;
private _installedExtensions: Promise<ILocalExtension[]>;
constructor(
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IProductService private readonly productService: IProductService,
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService
) {
super();
// This request goes to the shared process but results won't change during a window's lifetime, so cache the results.
this._installedExtensions = this.extensionManagementService.getInstalled(ExtensionType.User).then(exts => {
// Filter to enabled extensions that have settings
return exts
.filter(ext => this.extensionEnablementService.isEnabled(ext))
.filter(ext => ext.manifest && ext.manifest.contributes && ext.manifest.contributes.configuration)
.filter(ext => !!ext.identifier.uuid);
});
}
private get remoteSearchAllowed(): boolean {
const workbenchSettings = this.configurationService.getValue<IWorkbenchSettingsConfiguration>().workbench.settings;
if (!workbenchSettings.enableNaturalLanguageSearch) {
return false;
}
return !!this._endpoint.urlBase;
}
private get _endpoint(): IEndpointDetails {
const workbenchSettings = this.configurationService.getValue<IWorkbenchSettingsConfiguration>().workbench.settings;
if (workbenchSettings.naturalLanguageSearchEndpoint) {
return {
urlBase: workbenchSettings.naturalLanguageSearchEndpoint,
key: workbenchSettings.naturalLanguageSearchKey
};
} else {
return {
urlBase: this.productService.settingsSearchUrl
};
}
}
getRemoteSearchProvider(filter: string, newExtensionsOnly = false): ISearchProvider | undefined {
const opts: IRemoteSearchProviderOptions = {
filter,
newExtensionsOnly,
endpoint: this._endpoint
};
return this.remoteSearchAllowed ? this.instantiationService.createInstance(RemoteSearchProvider, opts, this._installedExtensions) : undefined;
}
getLocalSearchProvider(filter: string): LocalSearchProvider {
return this.instantiationService.createInstance(LocalSearchProvider, filter);
}
}
export class LocalSearchProvider implements ISearchProvider {
static readonly EXACT_MATCH_SCORE = 10000;
static readonly START_SCORE = 1000;
constructor(private _filter: string) {
// Remove " and : which are likely to be copypasted as part of a setting name.
// Leave other special characters which the user might want to search for.
this._filter = this._filter
.replace(/[":]/g, ' ')
.replace(/ /g, ' ')
.trim();
}
searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken): Promise<ISearchResult | null> {
if (!this._filter) {
return Promise.resolve(null);
}
let orderedScore = LocalSearchProvider.START_SCORE; // Sort is not stable
const settingMatcher = (setting: ISetting) => {
const matches = new SettingMatches(this._filter, setting, true, true, (filter, setting) => preferencesModel.findValueMatches(filter, setting)).matches;
const score = this._filter === setting.key ?
LocalSearchProvider.EXACT_MATCH_SCORE :
orderedScore--;
return matches && matches.length ?
{
matches,
score
} :
null;
};
const filterMatches = preferencesModel.filterSettings(this._filter, this.getGroupFilter(this._filter), settingMatcher);
if (filterMatches[0] && filterMatches[0].score === LocalSearchProvider.EXACT_MATCH_SCORE) {
return Promise.resolve({
filterMatches: filterMatches.slice(0, 1),
exactMatch: true
});
} else {
return Promise.resolve({
filterMatches
});
}
}
private getGroupFilter(filter: string): IGroupFilter {
const regex = strings.createRegExp(filter, false, { global: true });
return (group: ISettingsGroup) => {
return regex.test(group.title);
};
}
}
interface IRemoteSearchProviderOptions {
filter: string;
endpoint: IEndpointDetails;
newExtensionsOnly: boolean;
}
interface IBingRequestDetails {
url: string;
body?: string;
hasMoreFilters?: boolean;
extensions?: ILocalExtension[];
}
class RemoteSearchProvider implements ISearchProvider {
// Must keep extension filter size under 8kb. 42 filters puts us there.
private static readonly MAX_REQUEST_FILTERS = 42;
private static readonly MAX_REQUESTS = 10;
private static readonly NEW_EXTENSIONS_MIN_SCORE = 1;
private _remoteSearchP: Promise<IFilterMetadata | null>;
constructor(private options: IRemoteSearchProviderOptions, private installedExtensions: Promise<ILocalExtension[]>,
@IProductService private readonly productService: IProductService,
@IRequestService private readonly requestService: IRequestService,
@ILogService private readonly logService: ILogService
) {
this._remoteSearchP = this.options.filter ?
Promise.resolve(this.getSettingsForFilter(this.options.filter)) :
Promise.resolve(null);
}
searchModel(preferencesModel: ISettingsEditorModel, token?: CancellationToken): Promise<ISearchResult | null> {
return this._remoteSearchP.then<ISearchResult | null>((remoteResult) => {
if (!remoteResult) {
return null;
}
if (token && token.isCancellationRequested) {
throw canceled();
}
const resultKeys = Object.keys(remoteResult.scoredResults);
const highScoreKey = top(resultKeys, (a, b) => remoteResult.scoredResults[b].score - remoteResult.scoredResults[a].score, 1)[0];
const highScore = highScoreKey ? remoteResult.scoredResults[highScoreKey].score : 0;
const minScore = highScore / 5;
if (this.options.newExtensionsOnly) {
return this.installedExtensions.then(installedExtensions => {
const newExtsMinScore = Math.max(RemoteSearchProvider.NEW_EXTENSIONS_MIN_SCORE, minScore);
const passingScoreKeys = resultKeys
.filter(k => {
const result = remoteResult.scoredResults[k];
const resultExtId = (result.extensionPublisher + '.' + result.extensionName).toLowerCase();
return !installedExtensions.some(ext => ext.identifier.id.toLowerCase() === resultExtId);
})
.filter(k => remoteResult.scoredResults[k].score >= newExtsMinScore);
const filterMatches: ISettingMatch[] = passingScoreKeys.map(k => {
const remoteSetting = remoteResult.scoredResults[k];
const setting = remoteSettingToISetting(remoteSetting);
return <ISettingMatch>{
setting,
score: remoteSetting.score,
matches: [] // TODO
};
});
return <ISearchResult>{
filterMatches,
metadata: remoteResult
};
});
} else {
const settingMatcher = this.getRemoteSettingMatcher(remoteResult.scoredResults, minScore, preferencesModel);
const filterMatches = preferencesModel.filterSettings(this.options.filter, group => null, settingMatcher);
return <ISearchResult>{
filterMatches,
metadata: remoteResult
};
}
});
}
private async getSettingsForFilter(filter: string): Promise<IFilterMetadata> {
const allRequestDetails: IBingRequestDetails[] = [];
// Only send MAX_REQUESTS requests in total just to keep it sane
for (let i = 0; i < RemoteSearchProvider.MAX_REQUESTS; i++) {
const details = await this.prepareRequest(filter, i);
allRequestDetails.push(details);
if (!details.hasMoreFilters) {
break;
}
}
return Promise.all(allRequestDetails.map(details => this.getSettingsFromBing(details))).then(allResponses => {
// Merge all IFilterMetadata
const metadata = allResponses[0];
metadata.requestCount = 1;
for (const response of allResponses.slice(1)) {
metadata.requestCount++;
metadata.scoredResults = { ...metadata.scoredResults, ...response.scoredResults };
}
return metadata;
});
}
private getSettingsFromBing(details: IBingRequestDetails): Promise<IFilterMetadata> {
this.logService.debug(`Searching settings via ${details.url}`);
if (details.body) {
this.logService.debug(`Body: ${details.body}`);
}
const requestType = details.body ? 'post' : 'get';
const headers: IStringDictionary<string> = {
'User-Agent': 'request',
'Content-Type': 'application/json; charset=utf-8',
};
if (this.options.endpoint.key) {
headers['api-key'] = this.options.endpoint.key;
}
const start = Date.now();
return this.requestService.request({
type: requestType,
url: details.url,
data: details.body,
headers,
timeout: 5000
}, CancellationToken.None).then(context => {
if (typeof context.res.statusCode === 'number' && context.res.statusCode >= 300) {
throw new Error(`${JSON.stringify(details)} returned status code: ${context.res.statusCode}`);
}
return asJson(context);
}).then((result: any) => {
const timestamp = Date.now();
const duration = timestamp - start;
const remoteSettings: IRemoteSetting[] = (result.value || [])
.map((r: any) => {
const key = JSON.parse(r.setting || r.Setting);
const packageId = r['packageid'];
const id = getSettingKey(key, packageId);
const value = r['value'];
const defaultValue = value ? JSON.parse(value) : value;
const packageName = r['packagename'];
let extensionName: string | undefined;
let extensionPublisher: string | undefined;
if (packageName && packageName.indexOf('##') >= 0) {
[extensionPublisher, extensionName] = packageName.split('##');
}
return <IRemoteSetting>{
key,
id,
defaultValue,
score: r['@search.score'],
description: JSON.parse(r['details']),
packageId,
extensionName,
extensionPublisher
};
});
const scoredResults = Object.create(null);
remoteSettings.forEach(s => {
scoredResults[s.id] = s;
});
return <IFilterMetadata>{
requestUrl: details.url,
requestBody: details.body,
duration,
timestamp,
scoredResults,
context: result['@odata.context']
};
});
}
private getRemoteSettingMatcher(scoredResults: IScoredResults, minScore: number, preferencesModel: ISettingsEditorModel): ISettingMatcher {
return (setting: ISetting, group: ISettingsGroup) => {
const remoteSetting = scoredResults[getSettingKey(setting.key, group.id)] || // extension setting
scoredResults[getSettingKey(setting.key, 'core')] || // core setting
scoredResults[getSettingKey(setting.key)]; // core setting from original prod endpoint
if (remoteSetting && remoteSetting.score >= minScore) {
const settingMatches = new SettingMatches(this.options.filter, setting, false, true, (filter, setting) => preferencesModel.findValueMatches(filter, setting)).matches;
return { matches: settingMatches, score: remoteSetting.score };
}
return null;
};
}
private async prepareRequest(query: string, filterPage = 0): Promise<IBingRequestDetails> {
const verbatimQuery = query;
query = escapeSpecialChars(query);
const boost = 10;
const boostedQuery = `(${query})^${boost}`;
// Appending Fuzzy after each word.
query = query.replace(/\ +/g, '~ ') + '~';
const encodedQuery = encodeURIComponent(boostedQuery + ' || ' + query);
let url = `${this.options.endpoint.urlBase}`;
if (this.options.endpoint.key) {
url += `${API_VERSION}&${QUERY_TYPE}`;
}
const extensions = await this.installedExtensions;
const filters = this.options.newExtensionsOnly ?
[`diminish eq 'latest'`] :
this.getVersionFilters(extensions, this.productService.settingsSearchBuildId);
const filterStr = filters
.slice(filterPage * RemoteSearchProvider.MAX_REQUEST_FILTERS, (filterPage + 1) * RemoteSearchProvider.MAX_REQUEST_FILTERS)
.join(' or ');
const hasMoreFilters = filters.length > (filterPage + 1) * RemoteSearchProvider.MAX_REQUEST_FILTERS;
const body = JSON.stringify({
query: encodedQuery,
filters: encodeURIComponent(filterStr),
rawQuery: encodeURIComponent(verbatimQuery)
});
return {
url,
body,
hasMoreFilters
};
}
private getVersionFilters(exts: ILocalExtension[], buildNumber?: number): string[] {
// Only search extensions that contribute settings
const filters = exts
.filter(ext => ext.manifest.contributes && ext.manifest.contributes.configuration)
.map(ext => this.getExtensionFilter(ext));
if (buildNumber) {
filters.push(`(packageid eq 'core' and startbuildno le '${buildNumber}' and endbuildno ge '${buildNumber}')`);
}
return filters;
}
private getExtensionFilter(ext: ILocalExtension): string {
const uuid = ext.identifier.uuid;
const versionString = ext.manifest.version
.split('.')
.map(versionPart => strings.pad(<any>versionPart, 10))
.join('');
return `(packageid eq '${uuid}' and startbuildno le '${versionString}' and endbuildno ge '${versionString}')`;
}
}
function getSettingKey(name: string, packageId?: string): string {
return packageId ?
packageId + '##' + name :
name;
}
const API_VERSION = 'api-version=2016-09-01-Preview';
const QUERY_TYPE = 'querytype=full';
function escapeSpecialChars(query: string): string {
return query.replace(/\./g, ' ')
.replace(/[\\/+\-&|!"~*?:(){}\[\]\^]/g, '\\$&')
.replace(/ /g, ' ') // collapse spaces
.trim();
}
function remoteSettingToISetting(remoteSetting: IRemoteSetting): IExtensionSetting {
return {
description: remoteSetting.description.split('\n'),
descriptionIsMarkdown: false,
descriptionRanges: [],
key: remoteSetting.key,
keyRange: nullRange,
value: remoteSetting.defaultValue,
range: nullRange,
valueRange: nullRange,
overrides: [],
extensionName: remoteSetting.extensionName,
extensionPublisher: remoteSetting.extensionPublisher
};
}
export class SettingMatches {
private readonly descriptionMatchingWords: Map<string, IRange[]> = new Map<string, IRange[]>();
private readonly keyMatchingWords: Map<string, IRange[]> = new Map<string, IRange[]>();
private readonly valueMatchingWords: Map<string, IRange[]> = new Map<string, IRange[]>();
readonly matches: IRange[];
constructor(searchString: string, setting: ISetting, private requireFullQueryMatch: boolean, private searchDescription: boolean, private valuesMatcher: (filter: string, setting: ISetting) => IRange[]) {
this.matches = distinct(this._findMatchesInSetting(searchString, setting), (match) => `${match.startLineNumber}_${match.startColumn}_${match.endLineNumber}_${match.endColumn}_`);
}
private _findMatchesInSetting(searchString: string, setting: ISetting): IRange[] {
const result = this._doFindMatchesInSetting(searchString, setting);
if (setting.overrides && setting.overrides.length) {
for (const subSetting of setting.overrides) {
const subSettingMatches = new SettingMatches(searchString, subSetting, this.requireFullQueryMatch, this.searchDescription, this.valuesMatcher);
const words = searchString.split(' ');
const descriptionRanges: IRange[] = this.getRangesForWords(words, this.descriptionMatchingWords, [subSettingMatches.descriptionMatchingWords, subSettingMatches.keyMatchingWords, subSettingMatches.valueMatchingWords]);
const keyRanges: IRange[] = this.getRangesForWords(words, this.keyMatchingWords, [subSettingMatches.descriptionMatchingWords, subSettingMatches.keyMatchingWords, subSettingMatches.valueMatchingWords]);
const subSettingKeyRanges: IRange[] = this.getRangesForWords(words, subSettingMatches.keyMatchingWords, [this.descriptionMatchingWords, this.keyMatchingWords, subSettingMatches.valueMatchingWords]);
const subSettingValueRanges: IRange[] = this.getRangesForWords(words, subSettingMatches.valueMatchingWords, [this.descriptionMatchingWords, this.keyMatchingWords, subSettingMatches.keyMatchingWords]);
result.push(...descriptionRanges, ...keyRanges, ...subSettingKeyRanges, ...subSettingValueRanges);
result.push(...subSettingMatches.matches);
}
}
return result;
}
private _doFindMatchesInSetting(searchString: string, setting: ISetting): IRange[] {
const registry: { [qualifiedKey: string]: IJSONSchema } = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties();
const schema: IJSONSchema = registry[setting.key];
const words = searchString.split(' ');
const settingKeyAsWords: string = setting.key.split('.').join(' ');
for (const word of words) {
if (this.searchDescription) {
for (let lineIndex = 0; lineIndex < setting.description.length; lineIndex++) {
const descriptionMatches = matchesWords(word, setting.description[lineIndex], true);
if (descriptionMatches) {
this.descriptionMatchingWords.set(word, descriptionMatches.map(match => this.toDescriptionRange(setting, match, lineIndex)));
}
}
}
const keyMatches = or(matchesWords, matchesCamelCase)(word, settingKeyAsWords);
if (keyMatches) {
this.keyMatchingWords.set(word, keyMatches.map(match => this.toKeyRange(setting, match)));
}
const valueMatches = typeof setting.value === 'string' ? matchesContiguousSubString(word, setting.value) : null;
if (valueMatches) {
this.valueMatchingWords.set(word, valueMatches.map(match => this.toValueRange(setting, match)));
} else if (schema && schema.enum && schema.enum.some(enumValue => typeof enumValue === 'string' && !!matchesContiguousSubString(word, enumValue))) {
this.valueMatchingWords.set(word, []);
}
}
const descriptionRanges: IRange[] = [];
if (this.searchDescription) {
for (let lineIndex = 0; lineIndex < setting.description.length; lineIndex++) {
const matches = or(matchesContiguousSubString)(searchString, setting.description[lineIndex] || '') || [];
descriptionRanges.push(...matches.map(match => this.toDescriptionRange(setting, match, lineIndex)));
}
if (descriptionRanges.length === 0) {
descriptionRanges.push(...this.getRangesForWords(words, this.descriptionMatchingWords, [this.keyMatchingWords, this.valueMatchingWords]));
}
}
const keyMatches = or(matchesPrefix, matchesContiguousSubString)(searchString, setting.key);
const keyRanges: IRange[] = keyMatches ? keyMatches.map(match => this.toKeyRange(setting, match)) : this.getRangesForWords(words, this.keyMatchingWords, [this.descriptionMatchingWords, this.valueMatchingWords]);
let valueRanges: IRange[] = [];
if (setting.value && typeof setting.value === 'string') {
const valueMatches = or(matchesPrefix, matchesContiguousSubString)(searchString, setting.value);
valueRanges = valueMatches ? valueMatches.map(match => this.toValueRange(setting, match)) : this.getRangesForWords(words, this.valueMatchingWords, [this.keyMatchingWords, this.descriptionMatchingWords]);
} else {
valueRanges = this.valuesMatcher ? this.valuesMatcher(searchString, setting) : [];
}
return [...descriptionRanges, ...keyRanges, ...valueRanges];
}
private getRangesForWords(words: string[], from: Map<string, IRange[]>, others: Map<string, IRange[]>[]): IRange[] {
const result: IRange[] = [];
for (const word of words) {
const ranges = from.get(word);
if (ranges) {
result.push(...ranges);
} else if (this.requireFullQueryMatch && others.every(o => !o.has(word))) {
return [];
}
}
return result;
}
private toKeyRange(setting: ISetting, match: IMatch): IRange {
return {
startLineNumber: setting.keyRange.startLineNumber,
startColumn: setting.keyRange.startColumn + match.start,
endLineNumber: setting.keyRange.startLineNumber,
endColumn: setting.keyRange.startColumn + match.end
};
}
private toDescriptionRange(setting: ISetting, match: IMatch, lineIndex: number): IRange {
return {
startLineNumber: setting.descriptionRanges[lineIndex].startLineNumber,
startColumn: setting.descriptionRanges[lineIndex].startColumn + match.start,
endLineNumber: setting.descriptionRanges[lineIndex].endLineNumber,
endColumn: setting.descriptionRanges[lineIndex].startColumn + match.end
};
}
private toValueRange(setting: ISetting, match: IMatch): IRange {
return {
startLineNumber: setting.valueRange.startLineNumber,
startColumn: setting.valueRange.startColumn + match.start + 1,
endLineNumber: setting.valueRange.startLineNumber,
endColumn: setting.valueRange.startColumn + match.end + 1
};
}
}

View File

@@ -12,7 +12,7 @@ import { Action, IAction } from 'vs/base/common/actions';
import { Emitter, Event } from 'vs/base/common/event';
import { MarkdownString } from 'vs/base/common/htmlContent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { IMarginData } from 'vs/editor/browser/controller/mouseTarget';
import { ICodeEditor, IEditorMouseEvent, IViewZone, MouseTargetType } from 'vs/editor/browser/editorBrowser';
@@ -302,8 +302,6 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem {
private detailsElement: HTMLElement;
private dropDownElement: HTMLElement;
private disposables: IDisposable[] = [];
constructor(
action: IAction,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@@ -312,7 +310,7 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem {
super(null, action);
const workspace = this.contextService.getWorkspace();
this._folder = workspace.folders.length === 1 ? workspace.folders[0] : null;
this.disposables.push(this.contextService.onDidChangeWorkspaceFolders(() => this.onWorkspaceFoldersChanged()));
this._register(this.contextService.onDidChangeWorkspaceFolders(() => this.onWorkspaceFoldersChanged()));
}
get folder(): IWorkspaceFolder | null {
@@ -347,8 +345,8 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem {
'tabindex': '0'
}, this.labelElement, this.detailsElement, this.dropDownElement);
this._register(DOM.addDisposableListener(this.anchorElement, DOM.EventType.MOUSE_DOWN, e => DOM.EventHelper.stop(e)));
this.disposables.push(DOM.addDisposableListener(this.anchorElement, DOM.EventType.CLICK, e => this.onClick(e)));
this.disposables.push(DOM.addDisposableListener(this.anchorElement, DOM.EventType.KEY_UP, e => this.onKeyUp(e)));
this._register(DOM.addDisposableListener(this.anchorElement, DOM.EventType.CLICK, e => this.onClick(e)));
this._register(DOM.addDisposableListener(this.anchorElement, DOM.EventType.KEY_UP, e => this.onKeyUp(e)));
DOM.append(this.container, this.anchorElement);
@@ -460,11 +458,6 @@ export class FolderSettingsActionViewItem extends BaseActionViewItem {
return label;
}
dispose(): void {
dispose(this.disposables);
super.dispose();
}
}
export type SettingsTarget = ConfigurationTarget.USER_LOCAL | ConfigurationTarget.USER_REMOTE | ConfigurationTarget.WORKSPACE | URI;
@@ -484,7 +477,7 @@ export class SettingsTargetsWidget extends Widget {
private _settingsTarget: SettingsTarget;
private readonly _onDidTargetChange = new Emitter<SettingsTarget>();
private readonly _onDidTargetChange = this._register(new Emitter<SettingsTarget>());
readonly onDidTargetChange: Event<SettingsTarget> = this._onDidTargetChange.event;
constructor(
@@ -517,7 +510,7 @@ export class SettingsTargetsWidget extends Widget {
const remoteAuthority = this.environmentService.configuration.remoteAuthority;
const hostLabel = remoteAuthority && this.labelService.getHostLabel(REMOTE_HOST_SCHEME, remoteAuthority);
const remoteSettingsLabel = localize('userSettingsRemote', "Remote") +
(hostLabel ? ` (${hostLabel})` : '');
(hostLabel ? ` [${hostLabel}]` : '');
this.userRemoteSettings = new Action('userSettingsRemote', remoteSettingsLabel, '.settings-tab', true, () => this.updateTarget(ConfigurationTarget.USER_REMOTE));
this.userRemoteSettings.tooltip = this.userRemoteSettings.label;
@@ -751,8 +744,8 @@ export class EditPreferenceWidget<T> extends Disposable {
private _editPreferenceDecoration: string[];
private readonly _onClick = new Emitter<IEditorMouseEvent>();
get onClick(): Event<IEditorMouseEvent> { return this._onClick.event; }
private readonly _onClick = this._register(new Emitter<IEditorMouseEvent>());
readonly onClick: Event<IEditorMouseEvent> = this._onClick.event;
constructor(private editor: ICodeEditor
) {

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@ 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 } from 'vs/base/common/lifecycle';
import { dispose, IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { ISpliceable } from 'vs/base/common/sequence';
import { escapeRegExpCharacters, startsWith } from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri';
@@ -42,13 +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;
@@ -61,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 {
@@ -210,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 {
@@ -228,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';
@@ -249,7 +264,7 @@ export interface ISettingOverrideClickEvent {
targetKey: string;
}
export abstract class AbstractSettingRenderer implements ITreeRenderer<SettingsTreeElement, never, any> {
export abstract class AbstractSettingRenderer extends Disposable implements ITreeRenderer<SettingsTreeElement, never, any> {
/** To override */
abstract get templateId(): string;
@@ -261,19 +276,19 @@ export abstract class AbstractSettingRenderer implements ITreeRenderer<SettingsT
static readonly SETTING_KEY_ATTR = 'data-key';
static readonly SETTING_ID_ATTR = 'data-id';
private readonly _onDidClickOverrideElement = new Emitter<ISettingOverrideClickEvent>();
private readonly _onDidClickOverrideElement = this._register(new Emitter<ISettingOverrideClickEvent>());
readonly onDidClickOverrideElement: Event<ISettingOverrideClickEvent> = this._onDidClickOverrideElement.event;
protected readonly _onDidChangeSetting = new Emitter<ISettingChangeEvent>();
protected readonly _onDidChangeSetting = this._register(new Emitter<ISettingChangeEvent>());
readonly onDidChangeSetting: Event<ISettingChangeEvent> = this._onDidChangeSetting.event;
protected readonly _onDidOpenSettings = new Emitter<string>();
protected readonly _onDidOpenSettings = this._register(new Emitter<string>());
readonly onDidOpenSettings: Event<string> = this._onDidOpenSettings.event;
private readonly _onDidClickSettingLink = new Emitter<ISettingLinkClickEvent>();
private readonly _onDidClickSettingLink = this._register(new Emitter<ISettingLinkClickEvent>());
readonly onDidClickSettingLink: Event<ISettingLinkClickEvent> = this._onDidClickSettingLink.event;
private readonly _onDidFocusSetting = new Emitter<SettingsTreeSettingElement>();
private readonly _onDidFocusSetting = this._register(new Emitter<SettingsTreeSettingElement>());
readonly onDidFocusSetting: Event<SettingsTreeSettingElement> = this._onDidFocusSetting.event;
// Put common injections back here
@@ -287,6 +302,7 @@ export abstract class AbstractSettingRenderer implements ITreeRenderer<SettingsT
@IContextMenuService protected readonly _contextMenuService: IContextMenuService,
@IKeybindingService protected readonly _keybindingService: IKeybindingService,
) {
super();
}
renderTemplate(container: HTMLElement): any {
@@ -401,7 +417,9 @@ export abstract class AbstractSettingRenderer implements ITreeRenderer<SettingsT
template.descriptionElement.innerHTML = '';
if (element.setting.descriptionIsMarkdown) {
const renderedDescription = this.renderDescriptionMarkdown(element, element.description, template.toDispose);
const disposables = new DisposableStore();
template.toDispose.push(disposables);
const renderedDescription = this.renderDescriptionMarkdown(element, element.description, disposables);
template.descriptionElement.appendChild(renderedDescription);
} else {
template.descriptionElement.innerText = element.description;
@@ -445,7 +463,7 @@ export abstract class AbstractSettingRenderer implements ITreeRenderer<SettingsT
}
private renderDescriptionMarkdown(element: SettingsTreeSettingElement, text: string, disposeables: IDisposable[]): HTMLElement {
private renderDescriptionMarkdown(element: SettingsTreeSettingElement, text: string, disposeables: DisposableStore): HTMLElement {
// Rewrite `#editor.fontSize#` to link format
text = fixSettingLinks(text);
@@ -652,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);
@@ -669,46 +757,45 @@ 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;
}
}
const sortKeys = (obj: Object) => {
const keyArray = Object.keys(obj)
.map(key => ({ key, val: obj[key] }))
.sort((a, b) => a.key.localeCompare(b.key));
function sortKeys<T extends object>(obj: T) {
const sortedKeys = Object.keys(obj)
.sort((a, b) => a.localeCompare(b)) as Array<keyof T>;
const retVal = {};
keyArray.forEach(pair => {
retVal[pair.key] = pair.val;
});
const retVal: Partial<T> = {};
for (const key of sortedKeys) {
retVal[key] = obj[key];
}
return retVal;
};
}
this._onDidChangeSetting.fire({
key: template.context.setting.key,
@@ -939,11 +1026,11 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
const deprecationWarningElement = DOM.append(container, $('.setting-item-deprecation-message'));
const toDispose: IDisposable[] = [];
const toDispose = new DisposableStore();
const checkbox = new Checkbox({ actionClassName: 'setting-value-checkbox', isChecked: true, title: '', inputActiveOptionBorder: undefined });
controlElement.appendChild(checkbox.domNode);
toDispose.push(checkbox);
toDispose.push(checkbox.onChange(() => {
toDispose.add(checkbox);
toDispose.add(checkbox.onChange(() => {
if (template.onChange) {
template.onChange(checkbox.checked);
}
@@ -951,7 +1038,7 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
// Need to listen for mouse clicks on description and toggle checkbox - use target ID for safety
// Also have to ignore embedded links - too buried to stop propagation
toDispose.push(DOM.addDisposableListener(descriptionElement, DOM.EventType.MOUSE_DOWN, (e) => {
toDispose.add(DOM.addDisposableListener(descriptionElement, DOM.EventType.MOUSE_DOWN, (e) => {
const targetElement = <HTMLElement>e.target;
const targetId = descriptionElement.getAttribute('checkbox_label_target_id');
@@ -968,10 +1055,10 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
checkbox.domNode.classList.add(AbstractSettingRenderer.CONTROL_CLASS);
const toolbarContainer = DOM.append(container, $('.setting-toolbar-container'));
const toolbar = this.renderSettingToolbar(toolbarContainer);
toDispose.push(toolbar);
toDispose.add(toolbar);
const template: ISettingBoolItemTemplate = {
toDispose,
toDispose: [toDispose],
containerElement: container,
categoryElement,
@@ -987,16 +1074,16 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
this.addSettingElementFocusHandler(template);
// Prevent clicks from being handled by list
toDispose.push(DOM.addDisposableListener(controlElement, 'mousedown', (e: IMouseEvent) => e.stopPropagation()));
toDispose.add(DOM.addDisposableListener(controlElement, 'mousedown', (e: IMouseEvent) => e.stopPropagation()));
toDispose.push(DOM.addStandardDisposableListener(controlElement, 'keydown', (e: StandardKeyboardEvent) => {
toDispose.add(DOM.addStandardDisposableListener(controlElement, 'keydown', (e: StandardKeyboardEvent) => {
if (e.keyCode === KeyCode.Escape) {
e.browserEvent.stopPropagation();
}
}));
toDispose.push(DOM.addDisposableListener(titleElement, DOM.EventType.MOUSE_ENTER, e => container.classList.add('mouseover')));
toDispose.push(DOM.addDisposableListener(titleElement, DOM.EventType.MOUSE_LEAVE, e => container.classList.remove('mouseover')));
toDispose.add(DOM.addDisposableListener(titleElement, DOM.EventType.MOUSE_ENTER, e => container.classList.add('mouseover')));
toDispose.add(DOM.addDisposableListener(titleElement, DOM.EventType.MOUSE_LEAVE, e => container.classList.remove('mouseover')));
return template;
}
@@ -1053,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),
@@ -1163,6 +1251,7 @@ function escapeInvisibleChars(enumValue: string): string {
export class SettingsTreeFilter implements ITreeFilter<SettingsTreeElement> {
constructor(
private viewState: ISettingsEditorViewState,
@IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService,
) { }
filter(element: SettingsTreeElement, parentVisibility: TreeVisibility): TreeFilterResult<void> {
@@ -1175,7 +1264,8 @@ export class SettingsTreeFilter implements ITreeFilter<SettingsTreeElement> {
// Non-user scope selected
if (element instanceof SettingsTreeSettingElement && this.viewState.settingsTarget !== ConfigurationTarget.USER_LOCAL) {
if (!element.matchesScope(this.viewState.settingsTarget)) {
const isRemote = !!this.environmentService.configuration.remoteAuthority;
if (!element.matchesScope(this.viewState.settingsTarget, isRemote)) {
return false;
}
}
@@ -1249,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;
}
@@ -1303,7 +1397,8 @@ export class SettingsTree extends ObjectTree<SettingsTreeElement> {
container: HTMLElement,
viewState: ISettingsEditorViewState,
renderers: ITreeRenderer<any, void, any>[],
@IThemeService themeService: IThemeService
@IThemeService themeService: IThemeService,
@IInstantiationService instantiationService: IInstantiationService,
) {
const treeClass = 'settings-editor-tree';
@@ -1320,7 +1415,7 @@ export class SettingsTree extends ObjectTree<SettingsTreeElement> {
}
},
styleController: new DefaultStyleController(DOM.createStyleSheet(container), treeClass),
filter: new SettingsTreeFilter(viewState)
filter: instantiationService.createInstance(SettingsTreeFilter, viewState)
});
this.disposables = [];
@@ -1409,9 +1504,9 @@ class CopySettingIdAction extends Action {
super(CopySettingIdAction.ID, CopySettingIdAction.LABEL);
}
run(context: SettingsTreeSettingElement): Promise<void> {
async run(context: SettingsTreeSettingElement): Promise<void> {
if (context) {
this.clipboardService.writeText(context.setting.key);
await this.clipboardService.writeText(context.setting.key);
}
return Promise.resolve(undefined);
@@ -1428,10 +1523,10 @@ class CopySettingAsJSONAction extends Action {
super(CopySettingAsJSONAction.ID, CopySettingAsJSONAction.LABEL);
}
run(context: SettingsTreeSettingElement): Promise<void> {
async run(context: SettingsTreeSettingElement): Promise<void> {
if (context) {
const jsonResult = `"${context.setting.key}": ${JSON.stringify(context.value, undefined, ' ')}`;
this.clipboardService.writeText(jsonResult);
await this.clipboardService.writeText(jsonResult);
}
return Promise.resolve(undefined);

View File

@@ -14,6 +14,7 @@ import { SettingsTarget } from 'vs/workbench/contrib/preferences/browser/prefere
import { ITOCEntry, knownAcronyms, knownTermMappings } from 'vs/workbench/contrib/preferences/browser/settingsLayout';
import { MODIFIED_SETTING_TAG } from 'vs/workbench/contrib/preferences/common/preferences';
import { IExtensionSetting, ISearchResult, ISetting, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
export const ONLINE_SERVICES_SETTING_TAG = 'usesOnlineServices';
@@ -192,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;
@@ -221,7 +224,7 @@ export class SettingsTreeSettingElement extends SettingsTreeElement {
}
}
matchesScope(scope: SettingsTarget): boolean {
matchesScope(scope: SettingsTarget, isRemote: boolean): boolean {
const configTarget = URI.isUri(scope) ? ConfigurationTarget.WORKSPACE_FOLDER : scope;
if (configTarget === ConfigurationTarget.WORKSPACE_FOLDER) {
@@ -236,6 +239,10 @@ export class SettingsTreeSettingElement extends SettingsTreeElement {
return this.setting.scope === ConfigurationScope.MACHINE || this.setting.scope === ConfigurationScope.WINDOW || this.setting.scope === ConfigurationScope.RESOURCE;
}
if (configTarget === ConfigurationTarget.USER_LOCAL && isRemote) {
return this.setting.scope !== ConfigurationScope.MACHINE;
}
return true;
}
@@ -479,7 +486,8 @@ export class SearchResultModel extends SettingsTreeModel {
constructor(
viewState: ISettingsEditorViewState,
@IConfigurationService configurationService: IConfigurationService
@IConfigurationService configurationService: IConfigurationService,
@IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService,
) {
super(viewState, configurationService);
this.update({ id: 'searchResultModel', label: '' });
@@ -537,8 +545,9 @@ export class SearchResultModel extends SettingsTreeModel {
});
// Save time, filter children in the search model instead of relying on the tree filter, which still requires heights to be calculated.
const isRemote = !!this.environmentService.configuration.remoteAuthority;
this.root.children = this.root.children
.filter(child => child instanceof SettingsTreeSettingElement && child.matchesAllTags(this._viewState.tagFilters) && child.matchesScope(this._viewState.settingsTarget) && child.matchesAnyExtension(this._viewState.extensionFilters));
.filter(child => child instanceof SettingsTreeSettingElement && child.matchesAllTags(this._viewState.tagFilters) && child.matchesScope(this._viewState.settingsTarget, isRemote) && child.matchesAnyExtension(this._viewState.extensionFilters));
if (this.newExtensionSearchResults && this.newExtensionSearchResults.filterMatches.length) {
const newExtElement = new SettingsTreeNewExtensionsElement();

View File

@@ -12,7 +12,7 @@ import { IAction } from 'vs/base/common/actions';
import { Color, RGBA } from 'vs/base/common/color';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import 'vs/css!./media/settingsWidgets';
import { localize } from 'vs/nls';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
@@ -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 listDisposables: IDisposable[] = [];
private readonly listDisposables = this._register(new DisposableStore());
private model = new ExcludeSettingListModel();
private model = new ListSettingListModel();
private readonly _onDidChangeExclude = 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;
}
@@ -304,10 +323,10 @@ export class ExcludeSettingWidget extends Disposable {
const focused = DOM.isAncestor(document.activeElement, this.listElement);
DOM.clearNode(this.listElement);
this.listDisposables = dispose(this.listDisposables);
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,34 +363,34 @@ 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);
const actionBar = new ActionBar(rowElement);
this.listDisposables.push(actionBar);
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,68 +444,84 @@ 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.push(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.push(patternInput);
patternInput.value = item.pattern;
this.listDisposables.push(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');
this.listDisposables.push(siblingInput);
this.listDisposables.push(attachInputBoxStyler(siblingInput, this.themeService, {
siblingInput.element.classList.add('setting-list-siblingInput');
this.listDisposables.add(siblingInput);
this.listDisposables.add(attachInputBoxStyler(siblingInput, this.themeService, {
inputBackground: settingsTextInputBackground,
inputForeground: settingsTextInputForeground,
inputBorder: settingsTextInputBorder
}));
siblingInput.value = item.sibling;
this.listDisposables.push(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown));
this.listDisposables.add(DOM.addStandardDisposableListener(siblingInput.inputElement, DOM.EventType.KEY_DOWN, onKeydown));
}
const okButton = this._register(new Button(rowElement));
okButton.label = localize('okButton', "OK");
okButton.element.classList.add('setting-exclude-okButton');
this.listDisposables.push(attachButtonStyler(okButton, this.themeService));
this.listDisposables.push(okButton.onDidClick(() => onSubmit(true)));
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');
this.listDisposables.push(attachButtonStyler(cancelButton, this.themeService));
this.listDisposables.push(cancelButton.onDidClick(() => onSubmit(false)));
cancelButton.element.classList.add('setting-list-okButton');
this.listDisposables.add(attachButtonStyler(cancelButton, this.themeService));
this.listDisposables.add(cancelButton.onDidClick(() => onSubmit(false)));
this.listDisposables.push(
this.listDisposables.add(
disposableTimeout(() => {
patternInput.focus();
patternInput.select();
valueInput.focus();
valueInput.select();
}));
return rowElement;
}
}
dispose() {
super.dispose();
this.listDisposables = dispose(this.listDisposables);
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 IExcludeDataItem {
pattern: string;
export interface IListDataItem {
value: string;
sibling?: string;
}
interface IExcludeViewItem extends IExcludeDataItem {
interface IListViewItem extends IListDataItem {
editing?: boolean;
selected?: boolean;
}

View File

@@ -17,6 +17,7 @@ import { SettingsTreeFilter } from 'vs/workbench/contrib/preferences/browser/set
import { ISettingsEditorViewState, SearchResultModel, SettingsTreeElement, SettingsTreeGroupElement, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels';
import { settingsHeaderForeground } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
import { localize } from 'vs/nls';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
const $ = DOM.$;
@@ -25,7 +26,10 @@ export class TOCTreeModel {
private _currentSearchModel: SearchResultModel | null;
private _settingsTreeRoot: SettingsTreeGroupElement;
constructor(private _viewState: ISettingsEditorViewState) {
constructor(
private _viewState: ISettingsEditorViewState,
@IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService
) {
}
get settingsTreeRoot(): SettingsTreeGroupElement {
@@ -81,7 +85,8 @@ export class TOCTreeModel {
}
// Check everything that the SettingsFilter checks except whether it's filtered by a category
return child.matchesScope(this._viewState.settingsTarget) && child.matchesAllTags(this._viewState.tagFilters) && child.matchesAnyExtension(this._viewState.extensionFilters);
const isRemote = !!this.environmentService.configuration.remoteAuthority;
return child.matchesScope(this._viewState.settingsTarget, isRemote) && child.matchesAllTags(this._viewState.tagFilters) && child.matchesAnyExtension(this._viewState.extensionFilters);
}).length;
}
}
@@ -136,16 +141,12 @@ export function createTOCIterator(model: TOCTreeModel | SettingsTreeGroupElement
const groupChildren = <SettingsTreeGroupElement[]>model.children.filter(c => c instanceof SettingsTreeGroupElement);
const groupsIt = Iterator.fromArray(groupChildren);
return Iterator.map(groupsIt, g => {
let nodeExists = true;
try { tree.getNode(g); } catch (e) { nodeExists = false; }
const hasGroupChildren = g.children.some(c => c instanceof SettingsTreeGroupElement);
return {
element: g,
collapsed: nodeExists ? undefined : true,
collapsed: undefined,
collapsible: hasGroupChildren,
children: g instanceof SettingsTreeGroupElement ?
createTOCIterator(g, tree) :
@@ -198,7 +199,8 @@ export class TOCTree extends ObjectTree<SettingsTreeGroupElement> {
}
},
styleController: new DefaultStyleController(DOM.createStyleSheet(container), treeClass),
accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider)
accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider),
collapseByDefault: true
};
super(container,