Skip to content

Commit

Permalink
Use native tree filter and sorter
Browse files Browse the repository at this point in the history
So much cleaner using what's available
  • Loading branch information
TylerLeonhardt committed Aug 1, 2024
1 parent 5533ce3 commit 5d7650f
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 37 deletions.
82 changes: 46 additions & 36 deletions src/vs/platform/quickinput/browser/quickInputTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as dom from 'vs/base/browser/dom';
import { Emitter, Event, EventBufferer, IValueWithChangeEvent } from 'vs/base/common/event';
import { IHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegate';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { IObjectTreeElement, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { IObjectTreeElement, ITreeNode, ITreeRenderer, TreeVisibility } from 'vs/base/browser/ui/tree/tree';
import { localize } from 'vs/nls';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { WorkbenchObjectTree } from 'vs/platform/list/browser/listService';
Expand Down Expand Up @@ -39,7 +39,7 @@ import { isCancellationError } from 'vs/base/common/errors';
import type { IHoverWidget, IManagedHoverTooltipMarkdownString } from 'vs/base/browser/ui/hover/hover';
import { QuickPickFocus } from '../common/quickInput';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { observableValue, observableValueOpts } from 'vs/base/common/observable';
import { observableValue, observableValueOpts, transaction } from 'vs/base/common/observable';
import { equals } from 'vs/base/common/arrays';

const $ = dom.$;
Expand Down Expand Up @@ -554,6 +554,12 @@ class QuickPickSeparatorElementRenderer extends BaseQuickInputListRenderer<Quick
return this._visibleSeparatorsFrequency.has(separator);
}

override renderTemplate(container: HTMLElement): IQuickInputItemTemplateData {
const data = super.renderTemplate(container);
data.checkbox.style.display = 'none';
return data;
}

override renderElement(node: ITreeNode<QuickPickSeparatorElement, void>, index: number, data: IQuickInputItemTemplateData): void {
const element = node.element;
data.element = element;
Expand Down Expand Up @@ -707,6 +713,7 @@ export class QuickInputTree extends Disposable {
// Elements that apply to the current set of elements
private readonly _elementDisposable = this._register(new DisposableStore());
private _lastHover: IHoverWidget | undefined;
private _lastQueryString: string | undefined;

constructor(
private parent: HTMLElement,
Expand All @@ -727,6 +734,24 @@ export class QuickInputTree extends Disposable {
new QuickInputItemDelegate(),
[this._itemRenderer, this._separatorRenderer],
{
filter: {
filter(element) {
return element.hidden
? TreeVisibility.Hidden
: element instanceof QuickPickSeparatorElement
? TreeVisibility.Recurse
: TreeVisibility.Visible;
},
},
sorter: {
compare: (element, otherElement) => {
if (!this.sortByLabel || !this._lastQueryString) {
return 0;
}
const normalizedSearchValue = this._lastQueryString.toLowerCase();
return compareEntries(element, otherElement, normalizedSearchValue);
},
},
accessibilityProvider: new QuickInputAccessibilityProvider(),
setRowLineHeight: false,
multipleSelectionSupport: false,
Expand Down Expand Up @@ -1056,6 +1081,7 @@ export class QuickInputTree extends Disposable {

setElements(inputElements: QuickPickItem[]): void {
this._elementDisposable.clear();
this._lastQueryString = undefined;
this._inputElements = inputElements;
this._hasCheckboxes = this.parent.classList.contains('show-checkboxes');
let currentSeparatorElement: QuickPickSeparatorElement | undefined;
Expand Down Expand Up @@ -1363,6 +1389,7 @@ export class QuickInputTree extends Disposable {
}

filter(query: string): boolean {
this._lastQueryString = query;
if (!(this._sortByLabel || this._matchOnLabel || this._matchOnDescription || this._matchOnDetail)) {
this._tree.layout();
return false;
Expand All @@ -1388,7 +1415,7 @@ export class QuickInputTree extends Disposable {
// Filter by value (since we support icons in labels, use $(..) aware fuzzy matching)
else {
let currentSeparator: IQuickPickSeparator | undefined;
this._elementTree.forEach(element => {
this._itemElements.forEach(element => {
let labelHighlights: IMatch[] | undefined;
if (this.matchOnLabelMode === 'fuzzy') {
labelHighlights = this.matchOnLabel ? matchesFuzzyIconAware(query, parseLabelWithIcons(element.saneLabel)) ?? undefined : undefined;
Expand Down Expand Up @@ -1419,8 +1446,10 @@ export class QuickInputTree extends Disposable {

// we can show the separator unless the list gets sorted by match
if (!this.sortByLabel) {
const previous = element.index && this._inputElements[element.index - 1];
currentSeparator = previous && previous.type === 'separator' ? previous : currentSeparator;
const previous = element.index && this._inputElements[element.index - 1] || undefined;
if (previous?.type === 'separator' && !previous.buttons) {
currentSeparator = previous;
}
if (currentSeparator && !element.hidden) {
element.separator = currentSeparator;
currentSeparator = undefined;
Expand All @@ -1429,33 +1458,12 @@ export class QuickInputTree extends Disposable {
});
}

const shownElements = this._elementTree.filter(element => !element.hidden);

// Sort by value
if (this.sortByLabel && query) {
const normalizedSearchValue = query.toLowerCase();
shownElements.sort((a, b) => {
return compareEntries(a, b, normalizedSearchValue);
});
}

let currentSeparator: QuickPickSeparatorElement | undefined;
const finalElements = shownElements.reduce((result, element, index) => {
if (element instanceof QuickPickItemElement) {
if (currentSeparator) {
currentSeparator.children.push(element);
} else {
result.push(element);
}
} else if (element instanceof QuickPickSeparatorElement) {
element.children = [];
currentSeparator = element;
result.push(element);
}
return result;
}, new Array<IQuickPickElement>());

this._setElementsToTree(finalElements);
this._setElementsToTree(this._sortByLabel && query
// We don't render any separators if we're sorting so just render the elements
? this._itemElements
// Render the full tree
: this._elementTree
);
this._tree.layout();
return true;
}
Expand Down Expand Up @@ -1547,10 +1555,12 @@ export class QuickInputTree extends Disposable {
}

private _updateCheckedObservables() {
this._allVisibleCheckedObservable.set(this._allVisibleChecked(this._itemElements, false), undefined);
const checkedCount = this._itemElements.filter(element => element.checked).length;
this._checkedCountObservable.set(checkedCount, undefined);
this._checkedElementsObservable.set(this.getCheckedElements(), undefined);
transaction((tx) => {
this._allVisibleCheckedObservable.set(this._allVisibleChecked(this._itemElements, false), tx);
const checkedCount = this._itemElements.filter(element => element.checked).length;
this._checkedCountObservable.set(checkedCount, tx);
this._checkedElementsObservable.set(this.getCheckedElements(), tx);
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,10 +152,22 @@ export class ManageTrustedExtensionsForAccountAction extends Action2 {
};
};
const items: Array<TrustedExtensionsQuickPickItem | IQuickPickSeparator> = [
{
type: 'separator', label: localize('trustedExtensions', "Trusted by Microsoft"), buttons: [{
iconClass: 'codicon-gear',
tooltip: localize('manageTrustedExtensions', "Manage Trusted Extensions")
}]
},
...otherExtensions.sort(sortByLastUsed).map(toQuickPickItem),
{ type: 'separator', label: localize('trustedExtensions', "Trusted by Microsoft") },
{
type: 'separator', label: localize('trustedExtensions', "Trusted by Microsoft"), buttons: [{
iconClass: 'codicon-gear',
tooltip: localize('manageTrustedExtensions', "Manage Trusted Extensions")
}]
},
...trustedExtensions.sort(sortByLastUsed).map(toQuickPickItem)
];
quickPick.sortByLabel = false;

quickPick.items = items;
quickPick.selectedItems = items.filter((item): item is TrustedExtensionsQuickPickItem => item.type !== 'separator' && (item.extension.allowed === undefined || item.extension.allowed));
Expand Down

0 comments on commit 5d7650f

Please sign in to comment.