From ed604d1fe7cb27c79917aca2482ccfb8ca1fa232 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 9 Oct 2018 16:11:24 +0200 Subject: [PATCH] hook in filter to problems tree --- src/vs/base/browser/ui/tree/indexTreeModel.ts | 8 +- src/vs/base/browser/ui/tree/tree.ts | 8 +- .../electron-browser/markersFilterOptions.ts | 67 ++++++++ .../markers/electron-browser/markersModel.ts | 59 ------- .../markers/electron-browser/markersPanel.ts | 75 ++++++-- .../electron-browser/markersPanelActions.ts | 15 +- .../electron-browser/markersTreeViewer.ts | 162 ++++++++++++------ 7 files changed, 257 insertions(+), 137 deletions(-) create mode 100644 src/vs/workbench/parts/markers/electron-browser/markersFilterOptions.ts diff --git a/src/vs/base/browser/ui/tree/indexTreeModel.ts b/src/vs/base/browser/ui/tree/indexTreeModel.ts index c6b4304bf32..2b3570eb730 100644 --- a/src/vs/base/browser/ui/tree/indexTreeModel.ts +++ b/src/vs/base/browser/ui/tree/indexTreeModel.ts @@ -7,7 +7,7 @@ import { ISpliceable } from 'vs/base/common/sequence'; import { Iterator, ISequence } from 'vs/base/common/iterator'; import { Emitter, Event } from 'vs/base/common/event'; import { tail2 } from 'vs/base/common/arrays'; -import { ITreeFilterResult, TreeVisibility, ITreeFilter, ITreeOptions, ITreeModel, ITreeNode, ITreeElement } from 'vs/base/browser/ui/tree/tree'; +import { ITreeFilterDataResult, TreeVisibility, ITreeFilter, ITreeOptions, ITreeModel, ITreeNode, ITreeElement } from 'vs/base/browser/ui/tree/tree'; interface IMutableTreeNode extends ITreeNode { readonly parent: IMutableTreeNode | undefined; @@ -19,7 +19,7 @@ interface IMutableTreeNode extends ITreeNode { visible: boolean; } -function isFilterResult(obj: any): obj is ITreeFilterResult { +function isFilterResult(obj: any): obj is ITreeFilterDataResult { return typeof obj === 'object' && 'visibility' in obj && 'data' in obj; } @@ -30,8 +30,10 @@ function treeNodeToElement(node: IMutableTreeNode): ITreeElement { return { element, children, collapsed }; } -function getVisibleState(visibility: TreeVisibility): boolean | undefined { +function getVisibleState(visibility: boolean | TreeVisibility): boolean | undefined { switch (visibility) { + case true: return true; + case false: return false; case TreeVisibility.Hidden: return false; case TreeVisibility.Visible: return true; case TreeVisibility.Recurse: return undefined; diff --git a/src/vs/base/browser/ui/tree/tree.ts b/src/vs/base/browser/ui/tree/tree.ts index f219267f122..f1b4bb3ce53 100644 --- a/src/vs/base/browser/ui/tree/tree.ts +++ b/src/vs/base/browser/ui/tree/tree.ts @@ -12,13 +12,15 @@ export const enum TreeVisibility { Recurse // TODO@joao come up with a better name } -export interface ITreeFilterResult { - visibility: TreeVisibility; +export interface ITreeFilterDataResult { + visibility: boolean | TreeVisibility; data: TFilterData; } +export type TreeFilterResult = boolean | TreeVisibility | ITreeFilterDataResult; + export interface ITreeFilter { - filter(element: T): boolean | TreeVisibility | ITreeFilterResult; + filter(element: T): TreeFilterResult; } export interface ITreeOptions { diff --git a/src/vs/workbench/parts/markers/electron-browser/markersFilterOptions.ts b/src/vs/workbench/parts/markers/electron-browser/markersFilterOptions.ts new file mode 100644 index 00000000000..0398ddc3e33 --- /dev/null +++ b/src/vs/workbench/parts/markers/electron-browser/markersFilterOptions.ts @@ -0,0 +1,67 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import Messages from 'vs/workbench/parts/markers/electron-browser/messages'; +import { IFilter, or, matchesPrefix, matchesContiguousSubString, matchesFuzzy } from 'vs/base/common/filters'; +import { ParsedExpression, IExpression, splitGlobAware, getEmptyExpression, parse } from 'vs/base/common/glob'; +import * as strings from 'vs/base/common/strings'; + +export class FilterOptions { + + static readonly _filter: IFilter = or(matchesPrefix, matchesContiguousSubString); + static readonly _fuzzyFilter: IFilter = or(matchesPrefix, matchesContiguousSubString, matchesFuzzy); + + readonly filterErrors: boolean = false; + readonly filterWarnings: boolean = false; + readonly filterInfos: boolean = false; + readonly excludePattern: ParsedExpression = null; + readonly includePattern: ParsedExpression = null; + readonly textFilter: string = ''; + + constructor(readonly filter: string = '', excludePatterns: IExpression = {}) { + filter = filter.trim(); + for (const key of Object.keys(excludePatterns)) { + if (excludePatterns[key]) { + this.setPattern(excludePatterns, key); + } + delete excludePatterns[key]; + } + const includePatterns: IExpression = getEmptyExpression(); + if (filter) { + const filters = splitGlobAware(filter, ',').map(s => s.trim()).filter(s => !!s.length); + for (const f of filters) { + this.filterErrors = this.filterErrors || this.matches(f, Messages.MARKERS_PANEL_FILTER_ERRORS); + this.filterWarnings = this.filterWarnings || this.matches(f, Messages.MARKERS_PANEL_FILTER_WARNINGS); + this.filterInfos = this.filterInfos || this.matches(f, Messages.MARKERS_PANEL_FILTER_INFOS); + if (strings.startsWith(f, '!')) { + this.setPattern(excludePatterns, strings.ltrim(f, '!')); + } else { + this.setPattern(includePatterns, f); + this.textFilter += ` ${f}`; + } + } + } + if (Object.keys(excludePatterns).length) { + this.excludePattern = parse(excludePatterns); + } + if (Object.keys(includePatterns).length) { + this.includePattern = parse(includePatterns); + } + this.textFilter = this.textFilter.trim(); + } + + private setPattern(expression: IExpression, pattern: string) { + if (pattern[0] === '.') { + pattern = '*' + pattern; // convert ".js" to "*.js" + } + expression[`**/${pattern}/**`] = true; + expression[`**/${pattern}`] = true; + } + + private matches(prefix: string, word: string): boolean { + let result = matchesPrefix(prefix, word); + return result && result.length > 0; + } +} diff --git a/src/vs/workbench/parts/markers/electron-browser/markersModel.ts b/src/vs/workbench/parts/markers/electron-browser/markersModel.ts index 8dfc797ced8..c641b020cdd 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersModel.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersModel.ts @@ -75,65 +75,6 @@ export class RelatedInformation { constructor(readonly raw: IRelatedInformation) { } } -// TODO@joao -// export class FilterOptions { - -// static readonly _filter: IFilter = or(matchesPrefix, matchesContiguousSubString); -// static readonly _fuzzyFilter: IFilter = or(matchesPrefix, matchesContiguousSubString, matchesFuzzy); - -// readonly filterErrors: boolean = false; -// readonly filterWarnings: boolean = false; -// readonly filterInfos: boolean = false; -// readonly excludePattern: glob.ParsedExpression = null; -// readonly includePattern: glob.ParsedExpression = null; -// readonly textFilter: string = ''; - -// constructor(readonly filter: string = '', excludePatterns: glob.IExpression = {}) { -// filter = filter.trim(); -// for (const key of Object.keys(excludePatterns)) { -// if (excludePatterns[key]) { -// this.setPattern(excludePatterns, key); -// } -// delete excludePatterns[key]; -// } -// const includePatterns: glob.IExpression = glob.getEmptyExpression(); -// if (filter) { -// const filters = glob.splitGlobAware(filter, ',').map(s => s.trim()).filter(s => !!s.length); -// for (const f of filters) { -// this.filterErrors = this.filterErrors || this.matches(f, Messages.MARKERS_PANEL_FILTER_ERRORS); -// this.filterWarnings = this.filterWarnings || this.matches(f, Messages.MARKERS_PANEL_FILTER_WARNINGS); -// this.filterInfos = this.filterInfos || this.matches(f, Messages.MARKERS_PANEL_FILTER_INFOS); -// if (strings.startsWith(f, '!')) { -// this.setPattern(excludePatterns, strings.ltrim(f, '!')); -// } else { -// this.setPattern(includePatterns, f); -// this.textFilter += ` ${f}`; -// } -// } -// } -// if (Object.keys(excludePatterns).length) { -// this.excludePattern = glob.parse(excludePatterns); -// } -// if (Object.keys(includePatterns).length) { -// this.includePattern = glob.parse(includePatterns); -// } -// this.textFilter = this.textFilter.trim(); -// } - -// private setPattern(expression: glob.IExpression, pattern: string) { -// if (pattern[0] === '.') { -// pattern = '*' + pattern; // convert ".js" to "*.js" -// } -// expression[`**/${pattern}/**`] = true; -// expression[`**/${pattern}`] = true; -// } - -// private matches(prefix: string, word: string): boolean { -// let result = matchesPrefix(prefix, word); -// return result && result.length > 0; -// } -// } - export class MarkersModel { private cachedSortedResources: ResourceMarkers[] | undefined = undefined; diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts index 5415eb63c78..fc6a5458751 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanel.ts @@ -16,7 +16,7 @@ import Constants from 'vs/workbench/parts/markers/electron-browser/constants'; import { Marker, ResourceMarkers, RelatedInformation, MarkersModel } from 'vs/workbench/parts/markers/electron-browser/markersModel'; import * as Viewer from 'vs/workbench/parts/markers/electron-browser/markersTreeViewer'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { MarkersFilterActionItem, MarkersFilterAction, QuickFixAction, QuickFixActionItem } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions'; +import { MarkersFilterActionItem, MarkersFilterAction, QuickFixAction, QuickFixActionItem, IMarkersFilterActionChangeEvent } from 'vs/workbench/parts/markers/electron-browser/markersPanelActions'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import Messages from 'vs/workbench/parts/markers/electron-browser/messages'; import { RangeHighlightDecorations } from 'vs/workbench/browser/parts/editor/rangeDecorations'; @@ -31,6 +31,11 @@ import { Iterator } from 'vs/base/common/iterator'; import { ITreeElement } from 'vs/base/browser/ui/tree/tree'; import { debounceEvent } from 'vs/base/common/event'; import { WorkbenchObjectTree } from 'vs/platform/list/browser/listService'; +import { FilterOptions } from 'vs/workbench/parts/markers/electron-browser/markersFilterOptions'; +import { IExpression, getEmptyExpression } from 'vs/base/common/glob'; +import { mixin, deepClone } from 'vs/base/common/objects'; +import { IWorkspaceFolder, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; +import { isAbsolute, join } from 'vs/base/common/paths'; type TreeElement = ResourceMarkers | Marker | RelatedInformation; @@ -70,6 +75,8 @@ export class MarkersPanel extends Panel { private panelSettings: any; private panelFoucusContextKey: IContextKey; + private filter: Viewer.Filter; + private currentResourceGotAddedToMarkersData: boolean = false; constructor( @@ -80,7 +87,8 @@ export class MarkersPanel extends Panel { @IThemeService themeService: IThemeService, @IMarkersWorkbenchService private markersWorkbenchService: IMarkersWorkbenchService, @IStorageService storageService: IStorageService, - @IContextKeyService contextKeyService: IContextKeyService + @IContextKeyService contextKeyService: IContextKeyService, + @IWorkspaceContextService private workspaceContextService: IWorkspaceContextService, ) { super(Constants.MARKERS_PANEL_ID, telemetryService, themeService); this.panelFoucusContextKey = Constants.MarkerPanelFocusContextKey.bindTo(contextKeyService); @@ -103,7 +111,7 @@ export class MarkersPanel extends Panel { this.createActions(); this.createListeners(); - // this.updateFilter(); + this.updateFilter(); this.onDidFocus(() => this.panelFoucusContextKey.set(true)); this.onDidBlur(() => this.panelFoucusContextKey.set(false)); @@ -211,9 +219,49 @@ export class MarkersPanel extends Panel { return TPromise.as(null); } - // private updateFilter() { - // this.markersWorkbenchService.filter({ filterText: this.filterAction.filterText, useFilesExclude: this.filterAction.useFilesExclude }); - // } + private updateFilter() { + const excludeExpression = this.getExcludeExpression(this.filterAction.useFilesExclude); + this.filter.options = new FilterOptions(this.filterAction.filterText, excludeExpression); + this.tree.refilter(); + } + + private getExcludeExpression(useFilesExclude: boolean): IExpression { + if (!useFilesExclude) { + return {}; + } + + const workspaceFolders = this.workspaceContextService.getWorkspace().folders; + if (workspaceFolders.length) { + const result = getEmptyExpression(); + for (const workspaceFolder of workspaceFolders) { + mixin(result, this.getExcludesForFolder(workspaceFolder)); + } + return result; + } else { + return this.getFilesExclude(); + } + } + + private getExcludesForFolder(workspaceFolder: IWorkspaceFolder): IExpression { + const expression = this.getFilesExclude(workspaceFolder.uri); + return this.getAbsoluteExpression(expression, workspaceFolder.uri.fsPath); + } + + private getFilesExclude(resource?: URI): IExpression { + return deepClone(this.configurationService.getValue('files.exclude', { resource })) || {}; + } + + private getAbsoluteExpression(expr: IExpression, root: string): IExpression { + return Object.keys(expr) + .reduce((absExpr: IExpression, key: string) => { + if (expr[key] && !isAbsolute(key)) { + const absPattern = join(root, key); + absExpr[absPattern] = expr[key]; + } + + return absExpr; + }, Object.create(null)); + } private createMessageBox(parent: HTMLElement): void { this.messageBoxContainer = dom.append(parent, dom.$('.message-box-container')); @@ -239,12 +287,15 @@ export class MarkersPanel extends Panel { this.instantiationService.createInstance(Viewer.MarkerRenderer, a => this.getActionItem(a)), this.instantiationService.createInstance(Viewer.RelatedInformationRenderer) ]; + this.filter = new Viewer.Filter(); this.tree = this.instantiationService.createInstance(WorkbenchObjectTree, this.treeContainer, virtualDelegate, renderers, - {} + { + filter: this.filter + } ) as any as WorkbenchObjectTree; // this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, { @@ -296,11 +347,11 @@ export class MarkersPanel extends Panel { this._register(onModelChange(this.onDidChangeModel, this)); this._register(this.editorService.onDidActiveEditorChange(this.onActiveEditorChanged, this)); this._register(this.tree.onDidChangeSelection(() => this.onSelected())); - // this._register(this.filterAction.onDidChange((event: IMarkersFilterActionChangeEvent) => { - // if (event.filterText || event.useFilesExclude) { - // this.updateFilter(); - // } - // })); + this._register(this.filterAction.onDidChange((event: IMarkersFilterActionChangeEvent) => { + if (event.filterText || event.useFilesExclude) { + this.updateFilter(); + } + })); this.actions.forEach(a => this._register(a)); } diff --git a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts index b89e12a0f22..da4f41a8eb7 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersPanelActions.ts @@ -16,7 +16,6 @@ import Messages from 'vs/workbench/parts/markers/electron-browser/messages'; import Constants from 'vs/workbench/parts/markers/electron-browser/constants'; import { IPartService } from 'vs/workbench/services/part/common/partService'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { attachInputBoxStyler, attachStylerCallback, attachCheckboxStyler } from 'vs/platform/theme/common/styler'; import { IMarkersWorkbenchService } from 'vs/workbench/parts/markers/electron-browser/markers'; @@ -134,7 +133,7 @@ export class MarkersFilterActionItem extends BaseActionItem { @IContextViewService private contextViewService: IContextViewService, @IThemeService private themeService: IThemeService, @IMarkersWorkbenchService private markersWorkbenchService: IMarkersWorkbenchService, - @ITelemetryService private telemetryService: ITelemetryService, + // @ITelemetryService private telemetryService: ITelemetryService, @IContextKeyService contextKeyService: IContextKeyService ) { super(null, action); @@ -277,12 +276,12 @@ export class MarkersFilterActionItem extends BaseActionItem { } } + // TODO@joao private reportFilteringUsed(): void { - let data = {}; - console.warn('reportFilteringUsed not implemented'); // TODO@joao - // data['errors'] = this.markersWorkbenchService.markersModel.filterOptions.filterErrors; - // data['warnings'] = this.markersWorkbenchService.markersModel.filterOptions.filterWarnings; - // data['infos'] = this.markersWorkbenchService.markersModel.filterOptions.filterInfos; + // let data = {}; + // data['errors'] = this.filterOptions.filterErrors; + // data['warnings'] = this.filterOptions.filterWarnings; + // data['infos'] = this.filterOptions.filterInfos; /* __GDPR__ "problems.filter" : { "errors" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }, @@ -290,7 +289,7 @@ export class MarkersFilterActionItem extends BaseActionItem { "infos": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true } } */ - this.telemetryService.publicLog('problems.filter', data); + // this.telemetryService.publicLog('problems.filter', data); } } diff --git a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts index 3b9025155c3..31a4c1939bb 100644 --- a/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/electron-browser/markersTreeViewer.ts @@ -3,16 +3,15 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { TPromise, Promise } from 'vs/base/common/winjs.base'; import * as dom from 'vs/base/browser/dom'; import * as network from 'vs/base/common/network'; import * as paths from 'vs/base/common/paths'; -import { IDataSource, ITree, IAccessibilityProvider } from 'vs/base/parts/tree/browser/tree'; +import { ITree, IAccessibilityProvider } from 'vs/base/parts/tree/browser/tree'; import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge'; import { FileLabel, ResourceLabel } from 'vs/workbench/browser/labels'; import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel'; import { IMarker, MarkerSeverity } from 'vs/platform/markers/common/markers'; -import { MarkersModel, ResourceMarkers, Marker, RelatedInformation } from 'vs/workbench/parts/markers/electron-browser/markersModel'; +import { ResourceMarkers, Marker, RelatedInformation } from 'vs/workbench/parts/markers/electron-browser/markersModel'; import Messages from 'vs/workbench/parts/markers/electron-browser/messages'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { attachBadgeStyler } from 'vs/platform/theme/common/styler'; @@ -24,6 +23,9 @@ import { ILabelService } from 'vs/platform/label/common/label'; import { dirname } from 'vs/base/common/resources'; import { IVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { ITreeRenderer } from 'vs/base/browser/ui/tree/abstractTree'; +import { ITreeFilter, TreeVisibility, TreeFilterResult } from 'vs/base/browser/ui/tree/tree'; +import { FilterOptions } from 'vs/workbench/parts/markers/electron-browser/markersFilterOptions'; +import { IMatch } from 'vs/base/common/filters'; interface IResourceMarkersTemplateData { resourceLabel: ResourceLabel; @@ -46,55 +48,6 @@ interface IRelatedInformationTemplateData { description: HighlightedLabel; } -export class DataSource implements IDataSource { - public getId(tree: ITree, element: any): string { - if (element instanceof MarkersModel) { - return 'root'; - } - // if (element instanceof NodeWithId) { - // return element.id; - // } - return ''; - } - - public hasChildren(tree: ITree, element: any): boolean { - return element instanceof MarkersModel || element instanceof ResourceMarkers || (element instanceof Marker && element.relatedInformation.length > 0); - } - - public getChildren(tree: ITree, element: any): Promise { - if (element instanceof MarkersModel) { - return Promise.as(element.resourceMarkers); - } - if (element instanceof ResourceMarkers) { - return Promise.as(element.markers); - } - if (element instanceof Marker && element.relatedInformation.length > 0) { - return Promise.as(element.relatedInformation); - } - return null; - } - - public getParent(tree: ITree, element: any): Promise { - return TPromise.as(null); - } - - public shouldAutoexpand(tree: ITree, element: any): boolean { - if (element instanceof MarkersModel) { - return true; - } - - if (element instanceof ResourceMarkers) { - return true; - } - - if (element instanceof Marker && element.relatedInformation.length > 0) { - return true; - } - - return false; - } -} - export class MarkersTreeAccessibilityProvider implements IAccessibilityProvider { constructor( @@ -313,4 +266,109 @@ export class RelatedInformationRenderer implements ITreeRenderer { + + options = new FilterOptions(); + + filter(element: ResourceMarkers | Marker | RelatedInformation): TreeFilterResult { + if (element instanceof ResourceMarkers) { + return this.filterResourceMarkers(element); + } else if (element instanceof Marker) { + return this.filterMarker(element); + } else { + return this.filterRelatedInformation(element); + } + } + + private filterResourceMarkers(resourceMarkers: ResourceMarkers): TreeFilterResult { + if (resourceMarkers.resource.scheme === network.Schemas.walkThrough || resourceMarkers.resource.scheme === network.Schemas.walkThroughSnippet) { + return false; + } + + if (this.options.excludePattern && !!this.options.excludePattern(resourceMarkers.resource.fsPath)) { + return false; + } + + if (this.options.includePattern && this.options.includePattern(resourceMarkers.resource.fsPath)) { + return true; + } + + const uriMatches = FilterOptions._filter(this.options.textFilter, paths.basename(resourceMarkers.resource.fsPath)); + + if (this.options.textFilter && uriMatches) { + return { visibility: true, data: { type: FilterDataType.ResourceMarkers, uriMatches } }; + } + + return false; + } + + + private filterMarker(marker: Marker): TreeFilterResult { + if (this.options.filterErrors && MarkerSeverity.Error === marker.marker.severity) { + return true; + } + + if (this.options.filterWarnings && MarkerSeverity.Warning === marker.marker.severity) { + return true; + } + + if (this.options.filterInfos && MarkerSeverity.Info === marker.marker.severity) { + return true; + } + + if (!this.options.textFilter) { + return true; + } + + const messageMatches = FilterOptions._fuzzyFilter(this.options.textFilter, marker.marker.message); + const sourceMatches = marker.marker.source && FilterOptions._filter(this.options.textFilter, marker.marker.source); + const codeMatches = marker.marker.code && FilterOptions._filter(this.options.textFilter, marker.marker.code); + + if (messageMatches || sourceMatches || codeMatches) { + return { visibility: true, data: { type: FilterDataType.Marker, messageMatches: messageMatches || [], sourceMatches: sourceMatches || [], codeMatches: codeMatches || [] } }; + } + + return TreeVisibility.Recurse; + } + + private filterRelatedInformation(relatedInformation: RelatedInformation): TreeFilterResult { + if (!this.options.textFilter) { + return true; + } + + const uriMatches = FilterOptions._filter(this.options.textFilter, paths.basename(relatedInformation.raw.resource.fsPath)); + const messageMatches = FilterOptions._filter(this.options.textFilter, paths.basename(relatedInformation.raw.message)); + + if (uriMatches || messageMatches) { + return { visibility: true, data: { type: FilterDataType.RelatedInformation, uriMatches: uriMatches || [], messageMatches: messageMatches || [] } }; + } + + return false; + } } \ No newline at end of file -- GitLab