提交 95e4df26 编写于 作者: J Johannes Rieken

add filtering to breadcrumbs picker, #55004

上级 ebc9f5cd
......@@ -18,7 +18,7 @@ import { combinedDisposable, Disposable, dispose, IDisposable, toDisposable } fr
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { TPromise } from 'vs/base/common/winjs.base';
import { ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree';
import { IFilter, ITree, ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree';
import { ClickBehavior, DefaultController, DefaultTreestyler, IControllerOptions, OpenMode } from 'vs/base/parts/tree/browser/treeDefaults';
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
import { localize } from 'vs/nls';
......@@ -572,6 +572,10 @@ export interface IHighlightingTreeConfiguration extends ITreeConfiguration {
highlighter: IHighlighter;
}
export interface IHighlightingTreeOptions extends ITreeOptions {
filterOnType?: boolean;
}
export class HighlightingTreeController extends WorkbenchTreeController {
constructor(
......@@ -599,6 +603,41 @@ export class HighlightingTreeController extends WorkbenchTreeController {
}
}
class HightlightsFilter implements IFilter {
static add(config: ITreeConfiguration, options: IHighlightingTreeOptions): ITreeConfiguration {
let myFilter = new HightlightsFilter();
myFilter.enabled = options.filterOnType;
if (!config.filter) {
config.filter = myFilter;
} else {
let otherFilter = config.filter;
config.filter = {
isVisible(tree: ITree, element: any): boolean {
return myFilter.isVisible(tree, element) && otherFilter.isVisible(tree, element);
}
};
}
return config;
}
enabled: boolean = true;
isVisible(tree: ITree, element: any): boolean {
if (!this.enabled) {
return true;
}
let tree2 = (tree as HighlightingWorkbenchTree);
if (!tree2.isHighlighterScoring()) {
return true;
}
if (tree2.getHighlighterScore(element)) {
return true;
}
return false;
}
}
export class HighlightingWorkbenchTree extends WorkbenchTree {
protected readonly domNode: HTMLElement;
......@@ -611,7 +650,7 @@ export class HighlightingWorkbenchTree extends WorkbenchTree {
constructor(
parent: HTMLElement,
treeConfiguration: IHighlightingTreeConfiguration,
treeOptions: ITreeOptions,
treeOptions: IHighlightingTreeOptions,
listOptions: IInputOptions,
@IContextKeyService contextKeyService: IContextKeyService,
@IContextViewService contextViewService: IContextViewService,
......@@ -633,7 +672,7 @@ export class HighlightingWorkbenchTree extends WorkbenchTree {
// create tree
treeConfiguration.controller = treeConfiguration.controller || instantiationService.createInstance(HighlightingTreeController, {}, () => this.onTypeInTree());
super(treeContainer, treeConfiguration, treeOptions, contextKeyService, listService, themeService, instantiationService, configurationService);
super(treeContainer, HightlightsFilter.add(treeConfiguration, treeOptions), treeOptions, contextKeyService, listService, themeService, instantiationService, configurationService);
this.highlighter = treeConfiguration.highlighter;
this.highlights = new Map<any, FuzzyScore>();
......@@ -705,34 +744,42 @@ export class HighlightingWorkbenchTree extends WorkbenchTree {
this.lastSelection = [];
}
let nav = this.getNavigator(undefined, false);
let topScore: FuzzyScore;
let topElement: any;
while (nav.next()) {
let element = nav.current();
let score = this.highlighter.getHighlights(this, element, pattern);
this.highlights.set(this._getHighlightsStorageKey(element), score);
element.foo = 1;
if (!topScore || score && topScore[0] < score[0]) {
topScore = score;
topElement = element;
if (pattern) {
let nav = this.getNavigator(undefined, false);
let topScore: FuzzyScore;
while (nav.next()) {
let element = nav.current();
let score = this.highlighter.getHighlights(this, element, pattern);
this.highlights.set(this._getHighlightsStorageKey(element), score);
element.foo = 1;
if (!topScore || score && topScore[0] < score[0]) {
topScore = score;
topElement = element;
}
}
} else {
// no pattern, clear highlights
this.highlights.clear();
}
this.refresh().then(() => {
if (topElement && pattern) {
if (topElement) {
this.reveal(topElement, .5).then(_ => {
this.setSelection([topElement], this);
this.setFocus(topElement, this);
});
} else {
this.setSelection(defaultSelection, this);
this.highlights.clear();
}
}, onUnexpectedError);
}
getHighlights(element: any): FuzzyScore {
isHighlighterScoring(): boolean {
return this.highlights.size > 0;
}
getHighlighterScore(element: any): FuzzyScore {
return this.highlights.get(this._getHighlightsStorageKey(element));
}
......
......@@ -6,16 +6,16 @@
'use strict';
import { BreadcrumbsWidget } from 'vs/base/browser/ui/breadcrumbs/breadcrumbsWidget';
import { Emitter, Event } from 'vs/base/common/event';
import * as glob from 'vs/base/common/glob';
import { IDisposable } from 'vs/base/common/lifecycle';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { GroupIdentifier } from 'vs/workbench/common/editor';
import { localize } from 'vs/nls';
import { IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IConfigurationService, IConfigurationOverrides } from 'vs/platform/configuration/common/configuration';
import { Emitter, Event } from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
import { localize } from 'vs/nls';
import * as glob from 'vs/base/common/glob';
import { GroupIdentifier } from 'vs/workbench/common/editor';
export const IBreadcrumbsService = createDecorator<IBreadcrumbsService>('IEditorBreadcrumbsService');
......@@ -72,6 +72,7 @@ export abstract class BreadcrumbsConfig<T> {
static UseQuickPick = BreadcrumbsConfig._stub<boolean>('breadcrumbs.useQuickPick');
static FilePath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.filePath');
static SymbolPath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.symbolPath');
static FilterOnType = BreadcrumbsConfig._stub<boolean>('breadcrumbs.filterOnType');
static FileExcludes = BreadcrumbsConfig._stub<glob.IExpression>('files.exclude');
......@@ -143,6 +144,11 @@ Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfigurat
localize('symbolpath.last', "Only show the current symbol in the breadcrumbs view."),
]
},
'breadcrumbs.filterOnType': {
description: localize('filterOnType', "Controls whether the breadcrumb picker filters or highlights when typing."),
type: 'boolean',
default: false
},
}
});
......
......@@ -23,7 +23,7 @@ import { localize } from 'vs/nls';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { FileKind, IFileService, IFileStat } from 'vs/platform/files/common/files';
import { IConstructorSignature1, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { HighlightingWorkbenchTree, IHighlighter, IHighlightingTreeConfiguration } from 'vs/platform/list/browser/listService';
import { HighlightingWorkbenchTree, IHighlighter, IHighlightingTreeConfiguration, IHighlightingTreeOptions } from 'vs/platform/list/browser/listService';
import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
......@@ -55,6 +55,7 @@ export abstract class BreadcrumbsPicker {
parent: HTMLElement,
@IInstantiationService protected readonly _instantiationService: IInstantiationService,
@IThemeService protected readonly _themeService: IThemeService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
) {
this._domNode = document.createElement('div');
this._domNode.className = 'monaco-breadcrumbs-picker show-file-icons';
......@@ -79,12 +80,15 @@ export abstract class BreadcrumbsPicker {
this._treeContainer.style.boxShadow = `0px 5px 8px ${this._themeService.getTheme().getColor(widgetShadow)}`;
this._domNode.appendChild(this._treeContainer);
const filterConfig = BreadcrumbsConfig.FilterOnType.bindTo(this._configurationService);
this._disposables.push(filterConfig);
const treeConifg = this._completeTreeConfiguration({ dataSource: undefined, renderer: undefined, highlighter: undefined });
this._tree = this._instantiationService.createInstance(
HighlightingWorkbenchTree,
this._treeContainer,
treeConifg,
{ useShadows: false },
<IHighlightingTreeOptions>{ useShadows: false, filterOnType: filterConfig.getValue() },
{ placeholder: localize('placeholder', "Find") }
);
this._disposables.push(this._tree.onDidChangeSelection(e => {
......@@ -302,7 +306,7 @@ export class FileRenderer implements IRenderer {
fileKind,
hidePath: true,
fileDecorations: fileDecorations,
matches: createMatches((tree as HighlightingWorkbenchTree).getHighlights(element)),
matches: createMatches((tree as HighlightingWorkbenchTree).getHighlighterScore(element)),
extraClasses: ['picker-item']
});
}
......@@ -335,9 +339,10 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker {
parent: HTMLElement,
@IInstantiationService instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@IConfigurationService configService: IConfigurationService,
@IWorkspaceContextService private readonly _workspaceService: IWorkspaceContextService,
) {
super(parent, instantiationService, themeService);
super(parent, instantiationService, themeService, configService);
}
protected _getInput(input: BreadcrumbElement): any {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册