提交 0da60730 编写于 作者: J Joao Moreno

markers: filter with highlights

上级 e9809b3c
...@@ -11,7 +11,7 @@ import { append, $ } from 'vs/base/browser/dom'; ...@@ -11,7 +11,7 @@ import { append, $ } from 'vs/base/browser/dom';
import { Event, Relay, chain, mapEvent } from 'vs/base/common/event'; import { Event, Relay, chain, mapEvent } from 'vs/base/common/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes'; import { KeyCode } from 'vs/base/common/keyCodes';
import { ITreeModel, ITreeNode } from 'vs/base/browser/ui/tree/tree'; import { ITreeModel, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { ISpliceable } from 'vs/base/common/sequence'; import { ISpliceable } from 'vs/base/common/sequence';
import { IIndexTreeModelOptions } from 'vs/base/browser/ui/tree/indexTreeModel'; import { IIndexTreeModelOptions } from 'vs/base/browser/ui/tree/indexTreeModel';
import { memoize } from 'vs/base/common/decorators'; import { memoize } from 'vs/base/common/decorators';
...@@ -72,11 +72,6 @@ function renderDefaultTwistie<T>(node: ITreeNode<T, any>, twistie: HTMLElement): ...@@ -72,11 +72,6 @@ function renderDefaultTwistie<T>(node: ITreeNode<T, any>, twistie: HTMLElement):
} }
} }
export interface ITreeRenderer<TElement, TTemplateData> extends IRenderer<TElement, TTemplateData> {
renderTwistie?(element: TElement, twistieElement: HTMLElement): boolean;
onDidChangeTwistieState?: Event<TElement>;
}
class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode<T, TFilterData>, ITreeListTemplateData<TTemplateData>> { class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode<T, TFilterData>, ITreeListTemplateData<TTemplateData>> {
readonly templateId: string; readonly templateId: string;
...@@ -85,7 +80,7 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode ...@@ -85,7 +80,7 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode
private disposables: IDisposable[] = []; private disposables: IDisposable[] = [];
constructor( constructor(
private renderer: ITreeRenderer<T, TTemplateData>, private renderer: ITreeRenderer<T, TFilterData, TTemplateData>,
onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>> onDidChangeCollapseState: Event<ITreeNode<T, TFilterData>>
) { ) {
this.templateId = renderer.templateId; this.templateId = renderer.templateId;
...@@ -113,11 +108,11 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode ...@@ -113,11 +108,11 @@ class TreeRenderer<T, TFilterData, TTemplateData> implements IRenderer<ITreeNode
templateData.twistie.style.width = `${10 + node.depth * 10}px`; templateData.twistie.style.width = `${10 + node.depth * 10}px`;
this.renderTwistie(node, templateData.twistie); this.renderTwistie(node, templateData.twistie);
this.renderer.renderElement(node.element, index, templateData.templateData); this.renderer.renderElement(node, index, templateData.templateData);
} }
disposeElement(node: ITreeNode<T, TFilterData>, index: number, templateData: ITreeListTemplateData<TTemplateData>): void { disposeElement(node: ITreeNode<T, TFilterData>, index: number, templateData: ITreeListTemplateData<TTemplateData>): void {
this.renderer.disposeElement(node.element, index, templateData.templateData); this.renderer.disposeElement(node, index, templateData.templateData);
this.renderedNodes.delete(node); this.renderedNodes.delete(node);
this.renderedElements.set(node.element); this.renderedElements.set(node.element);
} }
...@@ -190,7 +185,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable ...@@ -190,7 +185,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
constructor( constructor(
container: HTMLElement, container: HTMLElement,
delegate: IVirtualDelegate<T>, delegate: IVirtualDelegate<T>,
renderers: ITreeRenderer<T, any>[], renderers: ITreeRenderer<T, TFilterData, any>[],
options?: ITreeOptions<T, TFilterData> options?: ITreeOptions<T, TFilterData>
) { ) {
const treeDelegate = new ComposedTreeDelegate<T, ITreeNode<T, TFilterData>>(delegate); const treeDelegate = new ComposedTreeDelegate<T, ITreeNode<T, TFilterData>>(delegate);
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information. * Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { ITreeOptions, ComposedTreeDelegate, createComposedTreeListOptions, ITreeRenderer } from 'vs/base/browser/ui/tree/abstractTree'; import { ITreeOptions, ComposedTreeDelegate, createComposedTreeListOptions } from 'vs/base/browser/ui/tree/abstractTree';
import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree'; import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { IVirtualDelegate, IRenderer } from 'vs/base/browser/ui/list/list'; import { IVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ITreeElement, ITreeNode } from 'vs/base/browser/ui/tree/tree'; import { ITreeElement, ITreeNode, ITreeRenderer, ITreeRenderElement } from 'vs/base/browser/ui/tree/tree';
import { IDisposable, dispose } from 'vs/base/common/lifecycle'; import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event'; import { Emitter, Event } from 'vs/base/common/event';
import { timeout } from 'vs/base/common/async'; import { timeout } from 'vs/base/common/async';
...@@ -39,14 +39,21 @@ interface IDataTreeListTemplateData<T> { ...@@ -39,14 +39,21 @@ interface IDataTreeListTemplateData<T> {
templateData: T; templateData: T;
} }
class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<T>, IDataTreeListTemplateData<TTemplateData>> { function unpack<T, TFilterData>(node: ITreeRenderElement<IDataTreeNode<T>, TFilterData>): ITreeRenderElement<T, TFilterData> {
return {
get element() { return node.element.element; },
get filterData() { return node.filterData; }
};
}
class DataTreeRenderer<T, TFilterData, TTemplateData> implements ITreeRenderer<IDataTreeNode<T>, TFilterData, IDataTreeListTemplateData<TTemplateData>> {
readonly templateId: string; readonly templateId: string;
private renderedNodes = new Map<IDataTreeNode<T>, IDataTreeListTemplateData<TTemplateData>>(); private renderedNodes = new Map<IDataTreeNode<T>, IDataTreeListTemplateData<TTemplateData>>();
private disposables: IDisposable[] = []; private disposables: IDisposable[] = [];
constructor( constructor(
private renderer: IRenderer<T, TTemplateData>, private renderer: ITreeRenderer<T, TFilterData, TTemplateData>,
readonly onDidChangeTwistieState: Event<IDataTreeNode<T>> readonly onDidChangeTwistieState: Event<IDataTreeNode<T>>
) { ) {
this.templateId = renderer.templateId; this.templateId = renderer.templateId;
...@@ -57,8 +64,8 @@ class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode< ...@@ -57,8 +64,8 @@ class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<
return { templateData }; return { templateData };
} }
renderElement(node: IDataTreeNode<T>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void { renderElement(element: ITreeRenderElement<IDataTreeNode<T>, TFilterData>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
this.renderer.renderElement(node.element, index, templateData.templateData); this.renderer.renderElement(unpack(element), index, templateData.templateData);
} }
renderTwistie(element: IDataTreeNode<T>, twistieElement: HTMLElement): boolean { renderTwistie(element: IDataTreeNode<T>, twistieElement: HTMLElement): boolean {
...@@ -70,8 +77,8 @@ class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode< ...@@ -70,8 +77,8 @@ class DataTreeRenderer<T, TTemplateData> implements ITreeRenderer<IDataTreeNode<
return false; return false;
} }
disposeElement(node: IDataTreeNode<T>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void { disposeElement(element: ITreeRenderElement<IDataTreeNode<T>, TFilterData>, index: number, templateData: IDataTreeListTemplateData<TTemplateData>): void {
this.renderer.disposeElement(node.element, index, templateData.templateData); this.renderer.disposeElement(unpack(element), index, templateData.templateData);
} }
disposeTemplate(templateData: IDataTreeListTemplateData<TTemplateData>): void { disposeTemplate(templateData: IDataTreeListTemplateData<TTemplateData>): void {
...@@ -97,7 +104,7 @@ export class DataTree<T extends NonNullable<any>, TFilterData = void> implements ...@@ -97,7 +104,7 @@ export class DataTree<T extends NonNullable<any>, TFilterData = void> implements
constructor( constructor(
container: HTMLElement, container: HTMLElement,
delegate: IVirtualDelegate<T>, delegate: IVirtualDelegate<T>,
renderers: ITreeRenderer<T, any>[], renderers: ITreeRenderer<T, TFilterData, any>[],
private dataSource: IDataSource<T>, private dataSource: IDataSource<T>,
options?: ITreeOptions<T, TFilterData> options?: ITreeOptions<T, TFilterData>
) { ) {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import { Event } from 'vs/base/common/event'; import { Event } from 'vs/base/common/event';
import { Iterator } from 'vs/base/common/iterator'; import { Iterator } from 'vs/base/common/iterator';
import { IRenderer } from 'vs/base/browser/ui/list/list';
export const enum TreeVisibility { export const enum TreeVisibility {
Hidden, Hidden,
...@@ -60,4 +61,14 @@ export interface ITreeModel<T, TFilterData, TRef> { ...@@ -60,4 +61,14 @@ export interface ITreeModel<T, TFilterData, TRef> {
getParentElement(location: TRef): T | null; getParentElement(location: TRef): T | null;
getFirstElementChild(location: TRef): T | null; getFirstElementChild(location: TRef): T | null;
getLastElementAncestor(location: TRef): T | null; getLastElementAncestor(location: TRef): T | null;
}
export interface ITreeRenderElement<T, TFilterData> {
readonly element: T;
readonly filterData: TFilterData | undefined;
}
export interface ITreeRenderer<T, TFilterData, TTemplateData> extends IRenderer<ITreeRenderElement<T, TFilterData>, TTemplateData> {
renderTwistie?(element: T, twistieElement: HTMLElement): boolean;
onDidChangeTwistieState?: Event<T>;
} }
\ No newline at end of file
...@@ -33,7 +33,8 @@ import { attachInputBoxStyler, attachListStyler, computeStyles, defaultListStyle ...@@ -33,7 +33,8 @@ import { attachInputBoxStyler, attachListStyler, computeStyles, defaultListStyle
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { InputFocusedContextKey } from 'vs/platform/workbench/common/contextkeys'; import { InputFocusedContextKey } from 'vs/platform/workbench/common/contextkeys';
import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree'; import { ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { ITreeRenderer, ITreeOptions as ITreeOptions2 } from 'vs/base/browser/ui/tree/abstractTree'; import { ITreeOptions as ITreeOptions2 } from 'vs/base/browser/ui/tree/abstractTree';
import { ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
export type ListWidget = List<any> | PagedList<any> | ITree | ObjectTree<any, any>; export type ListWidget = List<any> | PagedList<any> | ITree | ObjectTree<any, any>;
...@@ -814,7 +815,7 @@ export class WorkbenchObjectTree<T extends NonNullable<any>, TFilterData = void> ...@@ -814,7 +815,7 @@ export class WorkbenchObjectTree<T extends NonNullable<any>, TFilterData = void>
constructor( constructor(
container: HTMLElement, container: HTMLElement,
delegate: IVirtualDelegate<T>, delegate: IVirtualDelegate<T>,
renderers: ITreeRenderer<T, any>[], renderers: ITreeRenderer<T, TFilterData, any>[],
options: ITreeOptions2<T, TFilterData>, options: ITreeOptions2<T, TFilterData>,
@IContextKeyService contextKeyService: IContextKeyService, @IContextKeyService contextKeyService: IContextKeyService,
@IListService listService: IListService, @IListService listService: IListService,
......
...@@ -22,8 +22,7 @@ import { QuickFixAction } from 'vs/workbench/parts/markers/electron-browser/mark ...@@ -22,8 +22,7 @@ import { QuickFixAction } from 'vs/workbench/parts/markers/electron-browser/mark
import { ILabelService } from 'vs/platform/label/common/label'; import { ILabelService } from 'vs/platform/label/common/label';
import { dirname } from 'vs/base/common/resources'; import { dirname } from 'vs/base/common/resources';
import { IVirtualDelegate } from 'vs/base/browser/ui/list/list'; import { IVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { ITreeRenderer } from 'vs/base/browser/ui/tree/abstractTree'; import { ITreeFilter, TreeVisibility, TreeFilterResult, ITreeRenderer, ITreeRenderElement } from 'vs/base/browser/ui/tree/tree';
import { ITreeFilter, TreeVisibility, TreeFilterResult } from 'vs/base/browser/ui/tree/tree';
import { FilterOptions } from 'vs/workbench/parts/markers/electron-browser/markersFilterOptions'; import { FilterOptions } from 'vs/workbench/parts/markers/electron-browser/markersFilterOptions';
import { IMatch } from 'vs/base/common/filters'; import { IMatch } from 'vs/base/common/filters';
...@@ -99,7 +98,33 @@ export class VirtualDelegate implements IVirtualDelegate<ResourceMarkers | Marke ...@@ -99,7 +98,33 @@ export class VirtualDelegate implements IVirtualDelegate<ResourceMarkers | Marke
} }
} }
export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, IResourceMarkersTemplateData> { const enum FilterDataType {
ResourceMarkers,
Marker,
RelatedInformation
}
interface ResourceMarkersFilterData {
type: FilterDataType.ResourceMarkers;
uriMatches: IMatch[];
}
interface MarkerFilterData {
type: FilterDataType.Marker;
messageMatches: IMatch[];
sourceMatches: IMatch[];
codeMatches: IMatch[];
}
interface RelatedInformationFilterData {
type: FilterDataType.RelatedInformation;
uriMatches: IMatch[];
messageMatches: IMatch[];
}
type FilterData = ResourceMarkersFilterData | MarkerFilterData | RelatedInformationFilterData;
export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, ResourceMarkersFilterData, IResourceMarkersTemplateData> {
constructor( constructor(
@IInstantiationService protected instantiationService: IInstantiationService, @IInstantiationService protected instantiationService: IInstantiationService,
...@@ -123,14 +148,17 @@ export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, I ...@@ -123,14 +148,17 @@ export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, I
} }
// TODO@joao // TODO@joao
renderElement(element: ResourceMarkers, _: number, templateData: IResourceMarkersTemplateData): void { renderElement(element: ITreeRenderElement<ResourceMarkers, ResourceMarkersFilterData>, _: number, templateData: IResourceMarkersTemplateData): void {
const resourceMarkers = element.element;
const uriMatches = element.filterData && element.filterData.uriMatches || [];
if (templateData.resourceLabel instanceof FileLabel) { if (templateData.resourceLabel instanceof FileLabel) {
templateData.resourceLabel.setFile(element.resource/* , { matches: element.uriMatches } */); templateData.resourceLabel.setFile(resourceMarkers.resource, { matches: uriMatches });
} else { } else {
templateData.resourceLabel.setLabel({ name: element.name, description: this.labelService.getUriLabel(dirname(element.resource), { relative: true }), resource: element.resource }/* , { matches: element.uriMatches } */); templateData.resourceLabel.setLabel({ name: resourceMarkers.name, description: this.labelService.getUriLabel(dirname(resourceMarkers.resource), { relative: true }), resource: resourceMarkers.resource }, { matches: uriMatches });
} }
templateData.count.setCount(element.markers.length/* filteredCount */); // templateData.count.setCount(element.markers.length/* filteredCount */);
} }
disposeElement(): void { disposeElement(): void {
...@@ -156,7 +184,7 @@ export class FileResourceMarkersRenderer extends ResourceMarkersRenderer { ...@@ -156,7 +184,7 @@ export class FileResourceMarkersRenderer extends ResourceMarkersRenderer {
} }
} }
export class MarkerRenderer implements ITreeRenderer<Marker, IMarkerTemplateData> { export class MarkerRenderer implements ITreeRenderer<Marker, MarkerFilterData, IMarkerTemplateData> {
constructor( constructor(
private actionItemProvider: IActionItemProvider, private actionItemProvider: IActionItemProvider,
...@@ -177,24 +205,26 @@ export class MarkerRenderer implements ITreeRenderer<Marker, IMarkerTemplateData ...@@ -177,24 +205,26 @@ export class MarkerRenderer implements ITreeRenderer<Marker, IMarkerTemplateData
return data; return data;
} }
// TODO@joao renderElement(element: ITreeRenderElement<Marker, MarkerFilterData>, _: number, templateData: IMarkerTemplateData): void {
renderElement(element: Marker, _: number, templateData: IMarkerTemplateData): void { const marker = element.element.marker;
let marker = element.marker; const sourceMatches = element.filterData && element.filterData.sourceMatches || [];
const messageMatches = element.filterData && element.filterData.messageMatches || [];
const codeMatches = element.filterData && element.filterData.codeMatches || [];
templateData.icon.className = 'icon ' + MarkerRenderer.iconClassNameFor(marker); templateData.icon.className = 'icon ' + MarkerRenderer.iconClassNameFor(marker);
templateData.source.set(marker.source/* , element.sourceMatches */); templateData.source.set(marker.source, sourceMatches);
dom.toggleClass(templateData.source.element, 'marker-source', !!marker.source); dom.toggleClass(templateData.source.element, 'marker-source', !!marker.source);
templateData.actionBar.clear(); templateData.actionBar.clear();
const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element); const quickFixAction = this.instantiationService.createInstance(QuickFixAction, element.element);
templateData.actionBar.push([quickFixAction], { icon: true, label: false }); templateData.actionBar.push([quickFixAction], { icon: true, label: false });
templateData.description.set(marker.message/* , element.messageMatches */); templateData.description.set(marker.message, messageMatches);
templateData.description.element.title = marker.message; templateData.description.element.title = marker.message;
dom.toggleClass(templateData.code.element, 'marker-code', !!marker.code); dom.toggleClass(templateData.code.element, 'marker-code', !!marker.code);
templateData.code.set(marker.code || ''/* , element.codeMatches */); templateData.code.set(marker.code || '', codeMatches);
templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(marker.startLineNumber, marker.startColumn); templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(marker.startLineNumber, marker.startColumn);
} }
...@@ -224,7 +254,7 @@ export class MarkerRenderer implements ITreeRenderer<Marker, IMarkerTemplateData ...@@ -224,7 +254,7 @@ export class MarkerRenderer implements ITreeRenderer<Marker, IMarkerTemplateData
} }
} }
export class RelatedInformationRenderer implements ITreeRenderer<RelatedInformation, IRelatedInformationTemplateData> { export class RelatedInformationRenderer implements ITreeRenderer<RelatedInformation, RelatedInformationFilterData, IRelatedInformationTemplateData> {
constructor( constructor(
@ILabelService private labelService: ILabelService @ILabelService private labelService: ILabelService
...@@ -250,12 +280,16 @@ export class RelatedInformationRenderer implements ITreeRenderer<RelatedInformat ...@@ -250,12 +280,16 @@ export class RelatedInformationRenderer implements ITreeRenderer<RelatedInformat
} }
// TODO@joao // TODO@joao
renderElement(element: RelatedInformation, _: number, templateData: IRelatedInformationTemplateData): void { renderElement(element: ITreeRenderElement<RelatedInformation, RelatedInformationFilterData>, _: number, templateData: IRelatedInformationTemplateData): void {
templateData.resourceLabel.set(paths.basename(element.raw.resource.fsPath)/* , element.uriMatches */); const relatedInformation = element.element.raw;
templateData.resourceLabel.element.title = this.labelService.getUriLabel(element.raw.resource, { relative: true }); const uriMatches = element.filterData && element.filterData.uriMatches || [];
templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(element.raw.startLineNumber, element.raw.startColumn); const messageMatches = element.filterData && element.filterData.messageMatches || [];
templateData.description.set(element.raw.message/* , element.messageMatches */);
templateData.description.element.title = element.raw.message; templateData.resourceLabel.set(paths.basename(relatedInformation.resource.fsPath), uriMatches);
templateData.resourceLabel.element.title = this.labelService.getUriLabel(relatedInformation.resource, { relative: true });
templateData.lnCol.textContent = Messages.MARKERS_PANEL_AT_LINE_COL_NUMBER(relatedInformation.startLineNumber, relatedInformation.startColumn);
templateData.description.set(relatedInformation.message, messageMatches);
templateData.description.element.title = relatedInformation.message;
} }
disposeElement(): void { disposeElement(): void {
...@@ -268,30 +302,6 @@ export class RelatedInformationRenderer implements ITreeRenderer<RelatedInformat ...@@ -268,30 +302,6 @@ export class RelatedInformationRenderer implements ITreeRenderer<RelatedInformat
} }
} }
const enum FilterDataType {
ResourceMarkers,
Marker,
RelatedInformation
}
interface ResourceMarkersFilterData {
type: FilterDataType.ResourceMarkers;
uriMatches: IMatch[];
}
interface MarkerFilterData {
type: FilterDataType.Marker;
messageMatches: IMatch[];
sourceMatches: IMatch[];
codeMatches: IMatch[];
}
interface RelatedInformationFilterData {
type: FilterDataType.RelatedInformation;
}
type FilterData = ResourceMarkersFilterData | MarkerFilterData | RelatedInformationFilterData;
export class Filter implements ITreeFilter<ResourceMarkers | Marker | RelatedInformation, FilterData> { export class Filter implements ITreeFilter<ResourceMarkers | Marker | RelatedInformation, FilterData> {
options = new FilterOptions(); options = new FilterOptions();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册