sussudio
Version:
An unofficial VS Code Internal API
965 lines (964 loc) • 55.7 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { createStyleSheet } from "../../../base/browser/dom.mjs";
import { PagedList } from "../../../base/browser/ui/list/listPaging.mjs";
import { DefaultStyleController, isSelectionRangeChangeEvent, isSelectionSingleChangeEvent, List, TypeNavigationMode } from "../../../base/browser/ui/list/listWidget.mjs";
import { Table } from "../../../base/browser/ui/table/tableWidget.mjs";
import { TreeFindMode } from "../../../base/browser/ui/tree/abstractTree.mjs";
import { AsyncDataTree, CompressibleAsyncDataTree } from "../../../base/browser/ui/tree/asyncDataTree.mjs";
import { DataTree } from "../../../base/browser/ui/tree/dataTree.mjs";
import { CompressibleObjectTree, ObjectTree } from "../../../base/browser/ui/tree/objectTree.mjs";
import { Emitter, Event } from "../../../base/common/event.mjs";
import { combinedDisposable, Disposable, DisposableStore, dispose, toDisposable } from "../../../base/common/lifecycle.mjs";
import { localize } from "../../../nls.mjs";
import { IConfigurationService } from "../../configuration/common/configuration.mjs";
import { Extensions as ConfigurationExtensions } from "../../configuration/common/configurationRegistry.mjs";
import { ContextKeyExpr, IContextKeyService, RawContextKey } from "../../contextkey/common/contextkey.mjs";
import { InputFocusedContextKey } from "../../contextkey/common/contextkeys.mjs";
import { IContextViewService } from "../../contextview/browser/contextView.mjs";
import { createDecorator, IInstantiationService } from "../../instantiation/common/instantiation.mjs";
import { IKeybindingService } from "../../keybinding/common/keybinding.mjs";
import { Registry } from "../../registry/common/platform.mjs";
import { defaultFindWidgetStyles } from "../../theme/browser/defaultStyles.mjs";
import { attachListStyler, computeStyles, defaultListStyles } from "../../theme/common/styler.mjs";
import { IThemeService } from "../../theme/common/themeService.mjs";
export const IListService = createDecorator('listService');
let ListService = class ListService {
_themeService;
disposables = new DisposableStore();
lists = [];
_lastFocusedWidget = undefined;
_hasCreatedStyleController = false;
get lastFocusedList() {
return this._lastFocusedWidget;
}
constructor(_themeService) {
this._themeService = _themeService;
}
setLastFocusedList(widget) {
if (widget === this._lastFocusedWidget) {
return;
}
this._lastFocusedWidget?.getHTMLElement().classList.remove('last-focused');
this._lastFocusedWidget = widget;
this._lastFocusedWidget?.getHTMLElement().classList.add('last-focused');
}
register(widget, extraContextKeys) {
if (!this._hasCreatedStyleController) {
this._hasCreatedStyleController = true;
// create a shared default tree style sheet for performance reasons
const styleController = new DefaultStyleController(createStyleSheet(), '');
this.disposables.add(attachListStyler(styleController, this._themeService));
}
if (this.lists.some(l => l.widget === widget)) {
throw new Error('Cannot register the same widget multiple times');
}
// Keep in our lists list
const registeredList = { widget, extraContextKeys };
this.lists.push(registeredList);
// Check for currently being focused
if (widget.getHTMLElement() === document.activeElement) {
this.setLastFocusedList(widget);
}
return combinedDisposable(widget.onDidFocus(() => this.setLastFocusedList(widget)), toDisposable(() => this.lists.splice(this.lists.indexOf(registeredList), 1)), widget.onDidDispose(() => {
this.lists = this.lists.filter(l => l !== registeredList);
if (this._lastFocusedWidget === widget) {
this.setLastFocusedList(undefined);
}
}));
}
dispose() {
this.disposables.dispose();
}
};
ListService = __decorate([
__param(0, IThemeService)
], ListService);
export { ListService };
export const RawWorkbenchListFocusContextKey = new RawContextKey('listFocus', true);
export const WorkbenchListSupportsMultiSelectContextKey = new RawContextKey('listSupportsMultiselect', true);
export const WorkbenchListFocusContextKey = ContextKeyExpr.and(RawWorkbenchListFocusContextKey, ContextKeyExpr.not(InputFocusedContextKey));
export const WorkbenchListHasSelectionOrFocus = new RawContextKey('listHasSelectionOrFocus', false);
export const WorkbenchListDoubleSelection = new RawContextKey('listDoubleSelection', false);
export const WorkbenchListMultiSelection = new RawContextKey('listMultiSelection', false);
export const WorkbenchListSelectionNavigation = new RawContextKey('listSelectionNavigation', false);
export const WorkbenchListSupportsFind = new RawContextKey('listSupportsFind', true);
export const WorkbenchTreeElementCanCollapse = new RawContextKey('treeElementCanCollapse', false);
export const WorkbenchTreeElementHasParent = new RawContextKey('treeElementHasParent', false);
export const WorkbenchTreeElementCanExpand = new RawContextKey('treeElementCanExpand', false);
export const WorkbenchTreeElementHasChild = new RawContextKey('treeElementHasChild', false);
export const WorkbenchTreeFindOpen = new RawContextKey('treeFindOpen', false);
const WorkbenchListTypeNavigationModeKey = 'listTypeNavigationMode';
/**
* @deprecated in favor of WorkbenchListTypeNavigationModeKey
*/
const WorkbenchListAutomaticKeyboardNavigationLegacyKey = 'listAutomaticKeyboardNavigation';
function createScopedContextKeyService(contextKeyService, widget) {
const result = contextKeyService.createScoped(widget.getHTMLElement());
RawWorkbenchListFocusContextKey.bindTo(result);
return result;
}
const multiSelectModifierSettingKey = 'workbench.list.multiSelectModifier';
const openModeSettingKey = 'workbench.list.openMode';
const horizontalScrollingKey = 'workbench.list.horizontalScrolling';
const defaultFindModeSettingKey = 'workbench.list.defaultFindMode';
const typeNavigationModeSettingKey = 'workbench.list.typeNavigationMode';
/** @deprecated in favor of `workbench.list.defaultFindMode` and `workbench.list.typeNavigationMode` */
const keyboardNavigationSettingKey = 'workbench.list.keyboardNavigation';
const treeIndentKey = 'workbench.tree.indent';
const treeRenderIndentGuidesKey = 'workbench.tree.renderIndentGuides';
const listSmoothScrolling = 'workbench.list.smoothScrolling';
const mouseWheelScrollSensitivityKey = 'workbench.list.mouseWheelScrollSensitivity';
const fastScrollSensitivityKey = 'workbench.list.fastScrollSensitivity';
const treeExpandMode = 'workbench.tree.expandMode';
function useAltAsMultipleSelectionModifier(configurationService) {
return configurationService.getValue(multiSelectModifierSettingKey) === 'alt';
}
class MultipleSelectionController extends Disposable {
configurationService;
useAltAsMultipleSelectionModifier;
constructor(configurationService) {
super();
this.configurationService = configurationService;
this.useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService);
this.registerListeners();
}
registerListeners() {
this._register(this.configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(multiSelectModifierSettingKey)) {
this.useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(this.configurationService);
}
}));
}
isSelectionSingleChangeEvent(event) {
if (this.useAltAsMultipleSelectionModifier) {
return event.browserEvent.altKey;
}
return isSelectionSingleChangeEvent(event);
}
isSelectionRangeChangeEvent(event) {
return isSelectionRangeChangeEvent(event);
}
}
function toWorkbenchListOptions(accessor, options) {
const configurationService = accessor.get(IConfigurationService);
const keybindingService = accessor.get(IKeybindingService);
const disposables = new DisposableStore();
const result = {
...options,
keyboardNavigationDelegate: { mightProducePrintableCharacter(e) { return keybindingService.mightProducePrintableCharacter(e); } },
smoothScrolling: Boolean(configurationService.getValue(listSmoothScrolling)),
mouseWheelScrollSensitivity: configurationService.getValue(mouseWheelScrollSensitivityKey),
fastScrollSensitivity: configurationService.getValue(fastScrollSensitivityKey),
multipleSelectionController: options.multipleSelectionController ?? disposables.add(new MultipleSelectionController(configurationService)),
keyboardNavigationEventFilter: createKeyboardNavigationEventFilter(keybindingService),
};
return [result, disposables];
}
let WorkbenchList = class WorkbenchList extends List {
contextKeyService;
themeService;
listSupportsMultiSelect;
listHasSelectionOrFocus;
listDoubleSelection;
listMultiSelection;
horizontalScrolling;
_styler;
_useAltAsMultipleSelectionModifier;
navigator;
get onDidOpen() { return this.navigator.onDidOpen; }
constructor(user, container, delegate, renderers, options, contextKeyService, listService, themeService, configurationService, instantiationService) {
const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : Boolean(configurationService.getValue(horizontalScrollingKey));
const [workbenchListOptions, workbenchListOptionsDisposable] = instantiationService.invokeFunction(toWorkbenchListOptions, options);
super(user, container, delegate, renderers, {
keyboardSupport: false,
...computeStyles(themeService.getColorTheme(), defaultListStyles),
...workbenchListOptions,
horizontalScrolling
});
this.disposables.add(workbenchListOptionsDisposable);
this.contextKeyService = createScopedContextKeyService(contextKeyService, this);
this.themeService = themeService;
this.listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey.bindTo(this.contextKeyService);
this.listSupportsMultiSelect.set(options.multipleSelectionSupport !== false);
const listSelectionNavigation = WorkbenchListSelectionNavigation.bindTo(this.contextKeyService);
listSelectionNavigation.set(Boolean(options.selectionNavigation));
this.listHasSelectionOrFocus = WorkbenchListHasSelectionOrFocus.bindTo(this.contextKeyService);
this.listDoubleSelection = WorkbenchListDoubleSelection.bindTo(this.contextKeyService);
this.listMultiSelection = WorkbenchListMultiSelection.bindTo(this.contextKeyService);
this.horizontalScrolling = options.horizontalScrolling;
this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService);
this.disposables.add(this.contextKeyService);
this.disposables.add(listService.register(this));
if (options.overrideStyles) {
this.updateStyles(options.overrideStyles);
}
this.disposables.add(this.onDidChangeSelection(() => {
const selection = this.getSelection();
const focus = this.getFocus();
this.contextKeyService.bufferChangeEvents(() => {
this.listHasSelectionOrFocus.set(selection.length > 0 || focus.length > 0);
this.listMultiSelection.set(selection.length > 1);
this.listDoubleSelection.set(selection.length === 2);
});
}));
this.disposables.add(this.onDidChangeFocus(() => {
const selection = this.getSelection();
const focus = this.getFocus();
this.listHasSelectionOrFocus.set(selection.length > 0 || focus.length > 0);
}));
this.disposables.add(configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(multiSelectModifierSettingKey)) {
this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService);
}
let options = {};
if (e.affectsConfiguration(horizontalScrollingKey) && this.horizontalScrolling === undefined) {
const horizontalScrolling = Boolean(configurationService.getValue(horizontalScrollingKey));
options = { ...options, horizontalScrolling };
}
if (e.affectsConfiguration(listSmoothScrolling)) {
const smoothScrolling = Boolean(configurationService.getValue(listSmoothScrolling));
options = { ...options, smoothScrolling };
}
if (e.affectsConfiguration(mouseWheelScrollSensitivityKey)) {
const mouseWheelScrollSensitivity = configurationService.getValue(mouseWheelScrollSensitivityKey);
options = { ...options, mouseWheelScrollSensitivity };
}
if (e.affectsConfiguration(fastScrollSensitivityKey)) {
const fastScrollSensitivity = configurationService.getValue(fastScrollSensitivityKey);
options = { ...options, fastScrollSensitivity };
}
if (Object.keys(options).length > 0) {
this.updateOptions(options);
}
}));
this.navigator = new ListResourceNavigator(this, { configurationService, ...options });
this.disposables.add(this.navigator);
}
updateOptions(options) {
super.updateOptions(options);
if (options.overrideStyles) {
this.updateStyles(options.overrideStyles);
}
if (options.multipleSelectionSupport !== undefined) {
this.listSupportsMultiSelect.set(!!options.multipleSelectionSupport);
}
}
updateStyles(styles) {
this._styler?.dispose();
this._styler = attachListStyler(this, this.themeService, styles);
}
get useAltAsMultipleSelectionModifier() {
return this._useAltAsMultipleSelectionModifier;
}
dispose() {
this._styler?.dispose();
super.dispose();
}
};
WorkbenchList = __decorate([
__param(5, IContextKeyService),
__param(6, IListService),
__param(7, IThemeService),
__param(8, IConfigurationService),
__param(9, IInstantiationService)
], WorkbenchList);
export { WorkbenchList };
let WorkbenchPagedList = class WorkbenchPagedList extends PagedList {
contextKeyService;
themeService;
disposables;
listSupportsMultiSelect;
_useAltAsMultipleSelectionModifier;
horizontalScrolling;
_styler;
navigator;
get onDidOpen() { return this.navigator.onDidOpen; }
constructor(user, container, delegate, renderers, options, contextKeyService, listService, themeService, configurationService, instantiationService) {
const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : Boolean(configurationService.getValue(horizontalScrollingKey));
const [workbenchListOptions, workbenchListOptionsDisposable] = instantiationService.invokeFunction(toWorkbenchListOptions, options);
super(user, container, delegate, renderers, {
keyboardSupport: false,
...computeStyles(themeService.getColorTheme(), defaultListStyles),
...workbenchListOptions,
horizontalScrolling
});
this.disposables = new DisposableStore();
this.disposables.add(workbenchListOptionsDisposable);
this.contextKeyService = createScopedContextKeyService(contextKeyService, this);
this.themeService = themeService;
this.horizontalScrolling = options.horizontalScrolling;
this.listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey.bindTo(this.contextKeyService);
this.listSupportsMultiSelect.set(options.multipleSelectionSupport !== false);
const listSelectionNavigation = WorkbenchListSelectionNavigation.bindTo(this.contextKeyService);
listSelectionNavigation.set(Boolean(options.selectionNavigation));
this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService);
this.disposables.add(this.contextKeyService);
this.disposables.add(listService.register(this));
if (options.overrideStyles) {
this.updateStyles(options.overrideStyles);
}
if (options.overrideStyles) {
this.disposables.add(attachListStyler(this, themeService, options.overrideStyles));
}
this.disposables.add(configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(multiSelectModifierSettingKey)) {
this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService);
}
let options = {};
if (e.affectsConfiguration(horizontalScrollingKey) && this.horizontalScrolling === undefined) {
const horizontalScrolling = Boolean(configurationService.getValue(horizontalScrollingKey));
options = { ...options, horizontalScrolling };
}
if (e.affectsConfiguration(listSmoothScrolling)) {
const smoothScrolling = Boolean(configurationService.getValue(listSmoothScrolling));
options = { ...options, smoothScrolling };
}
if (e.affectsConfiguration(mouseWheelScrollSensitivityKey)) {
const mouseWheelScrollSensitivity = configurationService.getValue(mouseWheelScrollSensitivityKey);
options = { ...options, mouseWheelScrollSensitivity };
}
if (e.affectsConfiguration(fastScrollSensitivityKey)) {
const fastScrollSensitivity = configurationService.getValue(fastScrollSensitivityKey);
options = { ...options, fastScrollSensitivity };
}
if (Object.keys(options).length > 0) {
this.updateOptions(options);
}
}));
this.navigator = new ListResourceNavigator(this, { configurationService, ...options });
this.disposables.add(this.navigator);
}
updateOptions(options) {
super.updateOptions(options);
if (options.overrideStyles) {
this.updateStyles(options.overrideStyles);
}
if (options.multipleSelectionSupport !== undefined) {
this.listSupportsMultiSelect.set(!!options.multipleSelectionSupport);
}
}
updateStyles(styles) {
this._styler?.dispose();
this._styler = attachListStyler(this, this.themeService, styles);
}
get useAltAsMultipleSelectionModifier() {
return this._useAltAsMultipleSelectionModifier;
}
dispose() {
this._styler?.dispose();
this.disposables.dispose();
super.dispose();
}
};
WorkbenchPagedList = __decorate([
__param(5, IContextKeyService),
__param(6, IListService),
__param(7, IThemeService),
__param(8, IConfigurationService),
__param(9, IInstantiationService)
], WorkbenchPagedList);
export { WorkbenchPagedList };
let WorkbenchTable = class WorkbenchTable extends Table {
contextKeyService;
themeService;
listSupportsMultiSelect;
listHasSelectionOrFocus;
listDoubleSelection;
listMultiSelection;
horizontalScrolling;
_styler;
_useAltAsMultipleSelectionModifier;
navigator;
get onDidOpen() { return this.navigator.onDidOpen; }
constructor(user, container, delegate, columns, renderers, options, contextKeyService, listService, themeService, configurationService, instantiationService) {
const horizontalScrolling = typeof options.horizontalScrolling !== 'undefined' ? options.horizontalScrolling : Boolean(configurationService.getValue(horizontalScrollingKey));
const [workbenchListOptions, workbenchListOptionsDisposable] = instantiationService.invokeFunction(toWorkbenchListOptions, options);
super(user, container, delegate, columns, renderers, {
keyboardSupport: false,
...computeStyles(themeService.getColorTheme(), defaultListStyles),
...workbenchListOptions,
horizontalScrolling
});
this.disposables.add(workbenchListOptionsDisposable);
this.contextKeyService = createScopedContextKeyService(contextKeyService, this);
this.themeService = themeService;
this.listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey.bindTo(this.contextKeyService);
this.listSupportsMultiSelect.set(options.multipleSelectionSupport !== false);
const listSelectionNavigation = WorkbenchListSelectionNavigation.bindTo(this.contextKeyService);
listSelectionNavigation.set(Boolean(options.selectionNavigation));
this.listHasSelectionOrFocus = WorkbenchListHasSelectionOrFocus.bindTo(this.contextKeyService);
this.listDoubleSelection = WorkbenchListDoubleSelection.bindTo(this.contextKeyService);
this.listMultiSelection = WorkbenchListMultiSelection.bindTo(this.contextKeyService);
this.horizontalScrolling = options.horizontalScrolling;
this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService);
this.disposables.add(this.contextKeyService);
this.disposables.add(listService.register(this));
if (options.overrideStyles) {
this.updateStyles(options.overrideStyles);
}
this.disposables.add(this.onDidChangeSelection(() => {
const selection = this.getSelection();
const focus = this.getFocus();
this.contextKeyService.bufferChangeEvents(() => {
this.listHasSelectionOrFocus.set(selection.length > 0 || focus.length > 0);
this.listMultiSelection.set(selection.length > 1);
this.listDoubleSelection.set(selection.length === 2);
});
}));
this.disposables.add(this.onDidChangeFocus(() => {
const selection = this.getSelection();
const focus = this.getFocus();
this.listHasSelectionOrFocus.set(selection.length > 0 || focus.length > 0);
}));
this.disposables.add(configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(multiSelectModifierSettingKey)) {
this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService);
}
let options = {};
if (e.affectsConfiguration(horizontalScrollingKey) && this.horizontalScrolling === undefined) {
const horizontalScrolling = Boolean(configurationService.getValue(horizontalScrollingKey));
options = { ...options, horizontalScrolling };
}
if (e.affectsConfiguration(listSmoothScrolling)) {
const smoothScrolling = Boolean(configurationService.getValue(listSmoothScrolling));
options = { ...options, smoothScrolling };
}
if (e.affectsConfiguration(mouseWheelScrollSensitivityKey)) {
const mouseWheelScrollSensitivity = configurationService.getValue(mouseWheelScrollSensitivityKey);
options = { ...options, mouseWheelScrollSensitivity };
}
if (e.affectsConfiguration(fastScrollSensitivityKey)) {
const fastScrollSensitivity = configurationService.getValue(fastScrollSensitivityKey);
options = { ...options, fastScrollSensitivity };
}
if (Object.keys(options).length > 0) {
this.updateOptions(options);
}
}));
this.navigator = new TableResourceNavigator(this, { configurationService, ...options });
this.disposables.add(this.navigator);
}
updateOptions(options) {
super.updateOptions(options);
if (options.overrideStyles) {
this.updateStyles(options.overrideStyles);
}
if (options.multipleSelectionSupport !== undefined) {
this.listSupportsMultiSelect.set(!!options.multipleSelectionSupport);
}
}
updateStyles(styles) {
this._styler?.dispose();
this._styler = attachListStyler(this, this.themeService, styles);
}
get useAltAsMultipleSelectionModifier() {
return this._useAltAsMultipleSelectionModifier;
}
dispose() {
this._styler?.dispose();
this.disposables.dispose();
super.dispose();
}
};
WorkbenchTable = __decorate([
__param(6, IContextKeyService),
__param(7, IListService),
__param(8, IThemeService),
__param(9, IConfigurationService),
__param(10, IInstantiationService)
], WorkbenchTable);
export { WorkbenchTable };
export function getSelectionKeyboardEvent(typeArg = 'keydown', preserveFocus, pinned) {
const e = new KeyboardEvent(typeArg);
e.preserveFocus = preserveFocus;
e.pinned = pinned;
e.__forceEvent = true;
return e;
}
class ResourceNavigator extends Disposable {
widget;
openOnSingleClick;
_onDidOpen = this._register(new Emitter());
onDidOpen = this._onDidOpen.event;
constructor(widget, options) {
super();
this.widget = widget;
this._register(Event.filter(this.widget.onDidChangeSelection, e => e.browserEvent instanceof KeyboardEvent)(e => this.onSelectionFromKeyboard(e)));
this._register(this.widget.onPointer((e) => this.onPointer(e.element, e.browserEvent)));
this._register(this.widget.onMouseDblClick((e) => this.onMouseDblClick(e.element, e.browserEvent)));
if (typeof options?.openOnSingleClick !== 'boolean' && options?.configurationService) {
this.openOnSingleClick = options?.configurationService.getValue(openModeSettingKey) !== 'doubleClick';
this._register(options?.configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(openModeSettingKey)) {
this.openOnSingleClick = options?.configurationService.getValue(openModeSettingKey) !== 'doubleClick';
}
}));
}
else {
this.openOnSingleClick = options?.openOnSingleClick ?? true;
}
}
onSelectionFromKeyboard(event) {
if (event.elements.length !== 1) {
return;
}
const selectionKeyboardEvent = event.browserEvent;
const preserveFocus = typeof selectionKeyboardEvent.preserveFocus === 'boolean' ? selectionKeyboardEvent.preserveFocus : true;
const pinned = typeof selectionKeyboardEvent.pinned === 'boolean' ? selectionKeyboardEvent.pinned : !preserveFocus;
const sideBySide = false;
this._open(this.getSelectedElement(), preserveFocus, pinned, sideBySide, event.browserEvent);
}
onPointer(element, browserEvent) {
if (!this.openOnSingleClick) {
return;
}
const isDoubleClick = browserEvent.detail === 2;
if (isDoubleClick) {
return;
}
const isMiddleClick = browserEvent.button === 1;
const preserveFocus = true;
const pinned = isMiddleClick;
const sideBySide = browserEvent.ctrlKey || browserEvent.metaKey || browserEvent.altKey;
this._open(element, preserveFocus, pinned, sideBySide, browserEvent);
}
onMouseDblClick(element, browserEvent) {
if (!browserEvent) {
return;
}
// copied from AbstractTree
const target = browserEvent.target;
const onTwistie = target.classList.contains('monaco-tl-twistie')
|| (target.classList.contains('monaco-icon-label') && target.classList.contains('folder-icon') && browserEvent.offsetX < 16);
if (onTwistie) {
return;
}
const preserveFocus = false;
const pinned = true;
const sideBySide = (browserEvent.ctrlKey || browserEvent.metaKey || browserEvent.altKey);
this._open(element, preserveFocus, pinned, sideBySide, browserEvent);
}
_open(element, preserveFocus, pinned, sideBySide, browserEvent) {
if (!element) {
return;
}
this._onDidOpen.fire({
editorOptions: {
preserveFocus,
pinned,
revealIfVisible: true
},
sideBySide,
element,
browserEvent
});
}
}
class ListResourceNavigator extends ResourceNavigator {
widget;
constructor(widget, options) {
super(widget, options);
this.widget = widget;
}
getSelectedElement() {
return this.widget.getSelectedElements()[0];
}
}
class TableResourceNavigator extends ResourceNavigator {
constructor(widget, options) {
super(widget, options);
}
getSelectedElement() {
return this.widget.getSelectedElements()[0];
}
}
class TreeResourceNavigator extends ResourceNavigator {
constructor(widget, options) {
super(widget, options);
}
getSelectedElement() {
return this.widget.getSelection()[0] ?? undefined;
}
}
function createKeyboardNavigationEventFilter(keybindingService) {
let inMultiChord = false;
return event => {
if (event.toKeyCodeChord().isModifierKey()) {
return false;
}
if (inMultiChord) {
inMultiChord = false;
return false;
}
const result = keybindingService.softDispatch(event, event.target);
if (result?.enterMultiChord) {
inMultiChord = true;
return false;
}
inMultiChord = false;
return !result;
};
}
let WorkbenchObjectTree = class WorkbenchObjectTree extends ObjectTree {
internals;
get contextKeyService() { return this.internals.contextKeyService; }
get useAltAsMultipleSelectionModifier() { return this.internals.useAltAsMultipleSelectionModifier; }
get onDidOpen() { return this.internals.onDidOpen; }
constructor(user, container, delegate, renderers, options, instantiationService, contextKeyService, listService, themeService, configurationService) {
const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, options);
super(user, container, delegate, renderers, treeOptions);
this.disposables.add(disposable);
this.internals = new WorkbenchTreeInternals(this, options, getTypeNavigationMode, options.overrideStyles, contextKeyService, listService, themeService, configurationService);
this.disposables.add(this.internals);
}
updateOptions(options) {
super.updateOptions(options);
this.internals.updateOptions(options);
}
};
WorkbenchObjectTree = __decorate([
__param(5, IInstantiationService),
__param(6, IContextKeyService),
__param(7, IListService),
__param(8, IThemeService),
__param(9, IConfigurationService)
], WorkbenchObjectTree);
export { WorkbenchObjectTree };
let WorkbenchCompressibleObjectTree = class WorkbenchCompressibleObjectTree extends CompressibleObjectTree {
internals;
get contextKeyService() { return this.internals.contextKeyService; }
get useAltAsMultipleSelectionModifier() { return this.internals.useAltAsMultipleSelectionModifier; }
get onDidOpen() { return this.internals.onDidOpen; }
constructor(user, container, delegate, renderers, options, instantiationService, contextKeyService, listService, themeService, configurationService) {
const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, options);
super(user, container, delegate, renderers, treeOptions);
this.disposables.add(disposable);
this.internals = new WorkbenchTreeInternals(this, options, getTypeNavigationMode, options.overrideStyles, contextKeyService, listService, themeService, configurationService);
this.disposables.add(this.internals);
}
updateOptions(options = {}) {
super.updateOptions(options);
if (options.overrideStyles) {
this.internals.updateStyleOverrides(options.overrideStyles);
}
this.internals.updateOptions(options);
}
};
WorkbenchCompressibleObjectTree = __decorate([
__param(5, IInstantiationService),
__param(6, IContextKeyService),
__param(7, IListService),
__param(8, IThemeService),
__param(9, IConfigurationService)
], WorkbenchCompressibleObjectTree);
export { WorkbenchCompressibleObjectTree };
let WorkbenchDataTree = class WorkbenchDataTree extends DataTree {
internals;
get contextKeyService() { return this.internals.contextKeyService; }
get useAltAsMultipleSelectionModifier() { return this.internals.useAltAsMultipleSelectionModifier; }
get onDidOpen() { return this.internals.onDidOpen; }
constructor(user, container, delegate, renderers, dataSource, options, instantiationService, contextKeyService, listService, themeService, configurationService) {
const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, options);
super(user, container, delegate, renderers, dataSource, treeOptions);
this.disposables.add(disposable);
this.internals = new WorkbenchTreeInternals(this, options, getTypeNavigationMode, options.overrideStyles, contextKeyService, listService, themeService, configurationService);
this.disposables.add(this.internals);
}
updateOptions(options = {}) {
super.updateOptions(options);
if (options.overrideStyles) {
this.internals.updateStyleOverrides(options.overrideStyles);
}
this.internals.updateOptions(options);
}
};
WorkbenchDataTree = __decorate([
__param(6, IInstantiationService),
__param(7, IContextKeyService),
__param(8, IListService),
__param(9, IThemeService),
__param(10, IConfigurationService)
], WorkbenchDataTree);
export { WorkbenchDataTree };
let WorkbenchAsyncDataTree = class WorkbenchAsyncDataTree extends AsyncDataTree {
internals;
get contextKeyService() { return this.internals.contextKeyService; }
get useAltAsMultipleSelectionModifier() { return this.internals.useAltAsMultipleSelectionModifier; }
get onDidOpen() { return this.internals.onDidOpen; }
constructor(user, container, delegate, renderers, dataSource, options, instantiationService, contextKeyService, listService, themeService, configurationService) {
const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, options);
super(user, container, delegate, renderers, dataSource, treeOptions);
this.disposables.add(disposable);
this.internals = new WorkbenchTreeInternals(this, options, getTypeNavigationMode, options.overrideStyles, contextKeyService, listService, themeService, configurationService);
this.disposables.add(this.internals);
}
updateOptions(options = {}) {
super.updateOptions(options);
if (options.overrideStyles) {
this.internals.updateStyleOverrides(options.overrideStyles);
}
this.internals.updateOptions(options);
}
};
WorkbenchAsyncDataTree = __decorate([
__param(6, IInstantiationService),
__param(7, IContextKeyService),
__param(8, IListService),
__param(9, IThemeService),
__param(10, IConfigurationService)
], WorkbenchAsyncDataTree);
export { WorkbenchAsyncDataTree };
let WorkbenchCompressibleAsyncDataTree = class WorkbenchCompressibleAsyncDataTree extends CompressibleAsyncDataTree {
internals;
get contextKeyService() { return this.internals.contextKeyService; }
get useAltAsMultipleSelectionModifier() { return this.internals.useAltAsMultipleSelectionModifier; }
get onDidOpen() { return this.internals.onDidOpen; }
constructor(user, container, virtualDelegate, compressionDelegate, renderers, dataSource, options, instantiationService, contextKeyService, listService, themeService, configurationService) {
const { options: treeOptions, getTypeNavigationMode, disposable } = instantiationService.invokeFunction(workbenchTreeDataPreamble, options);
super(user, container, virtualDelegate, compressionDelegate, renderers, dataSource, treeOptions);
this.disposables.add(disposable);
this.internals = new WorkbenchTreeInternals(this, options, getTypeNavigationMode, options.overrideStyles, contextKeyService, listService, themeService, configurationService);
this.disposables.add(this.internals);
}
updateOptions(options) {
super.updateOptions(options);
this.internals.updateOptions(options);
}
};
WorkbenchCompressibleAsyncDataTree = __decorate([
__param(7, IInstantiationService),
__param(8, IContextKeyService),
__param(9, IListService),
__param(10, IThemeService),
__param(11, IConfigurationService)
], WorkbenchCompressibleAsyncDataTree);
export { WorkbenchCompressibleAsyncDataTree };
function getDefaultTreeFindMode(configurationService) {
const value = configurationService.getValue(defaultFindModeSettingKey);
if (value === 'highlight') {
return TreeFindMode.Highlight;
}
else if (value === 'filter') {
return TreeFindMode.Filter;
}
const deprecatedValue = configurationService.getValue(keyboardNavigationSettingKey);
if (deprecatedValue === 'simple' || deprecatedValue === 'highlight') {
return TreeFindMode.Highlight;
}
else if (deprecatedValue === 'filter') {
return TreeFindMode.Filter;
}
return undefined;
}
function workbenchTreeDataPreamble(accessor, options) {
const configurationService = accessor.get(IConfigurationService);
const contextViewService = accessor.get(IContextViewService);
const contextKeyService = accessor.get(IContextKeyService);
const instantiationService = accessor.get(IInstantiationService);
const getTypeNavigationMode = () => {
// give priority to the context key value to specify a value
const modeString = contextKeyService.getContextKeyValue(WorkbenchListTypeNavigationModeKey);
if (modeString === 'automatic') {
return TypeNavigationMode.Automatic;
}
else if (modeString === 'trigger') {
return TypeNavigationMode.Trigger;
}
// also check the deprecated context key to set the mode to 'trigger'
const modeBoolean = contextKeyService.getContextKeyValue(WorkbenchListAutomaticKeyboardNavigationLegacyKey);
if (modeBoolean === false) {
return TypeNavigationMode.Trigger;
}
// finally, check the setting
const configString = configurationService.getValue(typeNavigationModeSettingKey);
if (configString === 'automatic') {
return TypeNavigationMode.Automatic;
}
else if (configString === 'trigger') {
return TypeNavigationMode.Trigger;
}
return undefined;
};
const horizontalScrolling = options.horizontalScrolling !== undefined ? options.horizontalScrolling : Boolean(configurationService.getValue(horizontalScrollingKey));
const [workbenchListOptions, disposable] = instantiationService.invokeFunction(toWorkbenchListOptions, options);
const additionalScrollHeight = options.additionalScrollHeight;
return {
getTypeNavigationMode,
disposable,
options: {
// ...options, // TODO@Joao why is this not splatted here?
keyboardSupport: false,
...workbenchListOptions,
indent: typeof configurationService.getValue(treeIndentKey) === 'number' ? configurationService.getValue(treeIndentKey) : undefined,
renderIndentGuides: configurationService.getValue(treeRenderIndentGuidesKey),
smoothScrolling: Boolean(configurationService.getValue(listSmoothScrolling)),
defaultFindMode: getDefaultTreeFindMode(configurationService),
horizontalScrolling,
additionalScrollHeight,
hideTwistiesOfChildlessElements: options.hideTwistiesOfChildlessElements,
expandOnlyOnTwistieClick: options.expandOnlyOnTwistieClick ?? (configurationService.getValue(treeExpandMode) === 'doubleClick'),
contextViewProvider: contextViewService,
findWidgetStyles: defaultFindWidgetStyles
}
};
}
let WorkbenchTreeInternals = class WorkbenchTreeInternals {
tree;
themeService;
contextKeyService;
listSupportsMultiSelect;
listSupportFindWidget;
hasSelectionOrFocus;
hasDoubleSelection;
hasMultiSelection;
treeElementCanCollapse;
treeElementHasParent;
treeElementCanExpand;
treeElementHasChild;
treeFindOpen;
_useAltAsMultipleSelectionModifier;
disposables = [];
styler;
navigator;
get onDidOpen() { return this.navigator.onDidOpen; }
constructor(tree, options, getTypeNavigationMode, overrideStyles, contextKeyService, listService, themeService, configurationService) {
this.tree = tree;
this.themeService = themeService;
this.contextKeyService = createScopedContextKeyService(contextKeyService, tree);
this.listSupportsMultiSelect = WorkbenchListSupportsMultiSelectContextKey.bindTo(this.contextKeyService);
this.listSupportsMultiSelect.set(options.multipleSelectionSupport !== false);
const listSelectionNavigation = WorkbenchListSelectionNavigation.bindTo(this.contextKeyService);
listSelectionNavigation.set(Boolean(options.selectionNavigation));
this.listSupportFindWidget = WorkbenchListSupportsFind.bindTo(this.contextKeyService);
this.listSupportFindWidget.set(options.findWidgetEnabled ?? true);
this.hasSelectionOrFocus = WorkbenchListHasSelectionOrFocus.bindTo(this.contextKeyService);
this.hasDoubleSelection = WorkbenchListDoubleSelection.bindTo(this.contextKeyService);
this.hasMultiSelection = WorkbenchListMultiSelection.bindTo(this.contextKeyService);
this.treeElementCanCollapse = WorkbenchTreeElementCanCollapse.bindTo(this.contextKeyService);
this.treeElementHasParent = WorkbenchTreeElementHasParent.bindTo(this.contextKeyService);
this.treeElementCanExpand = WorkbenchTreeElementCanExpand.bindTo(this.contextKeyService);
this.treeElementHasChild = WorkbenchTreeElementHasChild.bindTo(this.contextKeyService);
this.treeFindOpen = WorkbenchTreeFindOpen.bindTo(this.contextKeyService);
this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService);
this.updateStyleOverrides(overrideStyles);
const updateCollapseContextKeys = () => {
const focus = tree.getFocus()[0];
if (!focus) {
return;
}
const node = tree.getNode(focus);
this.treeElementCanCollapse.set(node.collapsible && !node.collapsed);
this.treeElementHasParent.set(!!tree.getParentElement(focus));
this.treeElementCanExpand.set(node.collapsible && node.collapsed);
this.treeElementHasChild.set(!!tree.getFirstElementChild(focus));
};
const interestingContextKeys = new Set();
interestingContextKeys.add(WorkbenchListTypeNavigationModeKey);
interestingContextKeys.add(WorkbenchListAutomaticKeyboardNavigationLegacyKey);
this.disposables.push(this.contextKeyService, listService.register(tree), tree.onDidChangeSelection(() => {
const selection = tree.getSelection();
const focus = tree.getFocus();
this.contextKeyService.bufferChangeEvents(() => {
this.hasSelectionOrFocus.set(selection.length > 0 || focus.length > 0);
this.hasMultiSelection.set(selection.length > 1);
this.hasDoubleSelection.set(selection.length === 2);
});
}), tree.onDidChangeFocus(() => {
const selection = tree.getSelection();
const focus = tree.getFocus();
this.hasSelectionOrFocus.set(selection.length > 0 || focus.length > 0);
updateCollapseContextKeys();
}), tree.onDidChangeCollapseState(updateCollapseContextKeys), tree.onDidChangeModel(updateCollapseContextKeys), tree.onDidChangeFindOpenState(enabled => this.treeFindOpen.set(enabled)), configurationService.onDidChangeConfiguration(e => {
let newOptions = {};
if (e.affectsConfiguration(multiSelectModifierSettingKey)) {
this._useAltAsMultipleSelectionModifier = useAltAsMultipleSelectionModifier(configurationService);
}
if (e.affectsConfiguration(treeIndentKey)) {
const indent = configurationService.getValue(treeIndentKey);
newOptions = { ...newOptions, indent };
}
if (e.affectsConfiguration(treeRenderIndentGuidesKey)) {
const renderIndentGuides = configurationService.getValue(treeRenderIndentGuidesKey);
newOptions = { ...newOptions, renderIndentGuides };
}
if (e.affectsConfiguration(listSmoothScrolling)) {
const smoothScrolling = Boolean(configurationService.getValue(listSmoothScrolling));
newOptions = { ...newOptions, smoothScrolling };
}
if (e.affectsConfiguration(defaultFindModeSettingKey) || e.affectsConfiguration(keyboardNavigationSettingKey)) {
tree.updateOptions({ defaultFindMode: getDefaultTreeFindMode(configurationService) });
}
if (e.affectsConfiguration(typeNavigationModeSettingKey) || e.affectsConfiguration(keyboardNavigationSettingKey)) {
tree.updateOptions({ typeNavigationMode: getTypeNavigationMode() });
}
if (e.affectsConfiguration(horizontalScrollingKey) && options.horizontalScrolling === undefined) {
const horizontalScrolling = Boolean(configurationService.getValue(horizontalScrollingKey));
newOptions = { ...newOptions, horizontalScrolling };
}
if (e.affectsConfiguration(treeExpandMode) && options.expandOnlyOnTwistieClick === undefined) {
newOptions = { ...newOptions, expandOnlyOnTwistieClick: configurationService.getValue(treeExpandMode) === 'doubleClick' };
}
if (e.affectsConfiguration(mouseWheelScrollSensitivityKey)) {
const mouseWheelScrollSensitivity = configurationService.getValue(mouseWheelScrollSensitivityKey);
newOptions = { ...newOptions, mouseWheelScrollSensitivity };
}
if (e.affectsConfiguration(fastScrollSensitivityKey)) {
const fastScrollSensitivity = configurationService.getValue(fastScrollSensitivityKey);
newOptions = { ...newOptions, fastScrollSensitivity };
}
if (Object.keys(newOptions).length > 0) {
tree.updateOptions(newOptions);
}
}), this.contextKeyService.onDidChangeContext(e => {
if (e.affectsSome(interestingContextKeys)) {
tree.updateOptions({ typeNavigationMode: getTypeNavigationMode() });
}
}));
this.navigator = new TreeResourceNavigator(tree, { configurationService, ...options });
this.disposables.push(this.navigator);
}
get useAltAsMultipleSelectionModifier() {
return this._useAltAsMultipleSelectionModifier;
}
updateOptions(options) {
if (options.multipleSelectionSupport !== undefined) {
this.listSupportsMultiSelect.set(!!options.multipleSelectionSupport);
}
}
updateStyleOverrides(overrideStyles) {
dispose(this.styler);
this.styler = attachListStyler(this.tree, this.themeService, overrideStyles);
}
dispose() {
this.disposables = dispose(this.disposables);
dispose(this.styler);
this.styler = undefined;
}
};
WorkbenchTreeInternals = __decorate([
__param(4, IContextKeyService),
__param(5, IListService),
__param(6, IThemeService),
__param(7, IConfigurationService)
], WorkbenchTreeInternals);
const configurationRegistry = Registry.as(ConfigurationExtensions.Configuration);
configurationRegistry.registerConfiguration({
id: 'workbench',
order: 7,
title: localize('workbenchConfigurationTitle', "Workbench"),
type: 'object',
properties: {
[multiSelectModifierSettingKey]: {
type: 'string',