diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts index d143e4b1d45f502c66d3b3125520aa1d32f562e2..940ddfdc570c5af4c03fa5f6962d318905ee78de 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbs.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbs.ts @@ -15,6 +15,7 @@ import { Emitter, Event } from 'vs/base/common/event'; 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'; export const IBreadcrumbsService = createDecorator('IEditorBreadcrumbsService'); @@ -59,8 +60,8 @@ export abstract class BreadcrumbsConfig { name: string; onDidChange: Event; - abstract getValue(): T; - abstract updateValue(value: T): Thenable; + abstract getValue(overrides?: IConfigurationOverrides): T; + abstract updateValue(value: T, overrides?: IConfigurationOverrides): Thenable; abstract dispose(): void; private constructor() { @@ -72,6 +73,8 @@ export abstract class BreadcrumbsConfig { static FilePath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.filePath'); static SymbolPath = BreadcrumbsConfig._stub<'on' | 'off' | 'last'>('breadcrumbs.symbolPath'); + static FileExcludes = BreadcrumbsConfig._stub('files.exclude'); + private static _stub(name: string): { bindTo(service: IConfigurationService): BreadcrumbsConfig } { return { bindTo(service) { diff --git a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts index fa0613810465ec4415aff4e120d4e6c8412d09d0..0efbd1a09098de3da71c1f646f47584f55b94df9 100644 --- a/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts +++ b/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.ts @@ -9,10 +9,10 @@ import * as dom from 'vs/base/browser/dom'; import { compareFileNames } from 'vs/base/common/comparers'; import { Emitter, Event } from 'vs/base/common/event'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; -import { dirname, isEqual } from 'vs/base/common/resources'; +import { dirname, isEqual, basename } from 'vs/base/common/resources'; import URI from 'vs/base/common/uri'; import { TPromise } from 'vs/base/common/winjs.base'; -import { IDataSource, IRenderer, ISelectionEvent, ISorter, ITree } from 'vs/base/parts/tree/browser/tree'; +import { IDataSource, IRenderer, ISelectionEvent, ISorter, ITree, IFilter } from 'vs/base/parts/tree/browser/tree'; import 'vs/css!./media/breadcrumbscontrol'; import { OutlineElement, OutlineModel, TreeElement } from 'vs/editor/contrib/documentSymbols/outlineModel'; import { OutlineDataSource, OutlineItemComparator, OutlineRenderer } from 'vs/editor/contrib/documentSymbols/outlineTree'; @@ -28,6 +28,9 @@ import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/com import { FuzzyScore, createMatches, fuzzyScore } from 'vs/base/common/filters'; import { IWorkspaceContextService, IWorkspace, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { BreadcrumbsConfig } from 'vs/workbench/browser/parts/editor/breadcrumbs'; +import * as glob from 'vs/base/common/glob'; +import { } from 'vs/base/common/paths'; export function createBreadcrumbsPicker(instantiationService: IInstantiationService, parent: HTMLElement, element: BreadcrumbElement): BreadcrumbsPicker { let ctor: IConstructorSignature1 = element instanceof FileElement ? BreadcrumbsFilePicker : BreadcrumbsOutlinePicker; @@ -203,6 +206,52 @@ export class FileDataSource implements IDataSource { } } +export class FileFilter implements IFilter { + + private readonly _cachedExpressions = new Map(); + private readonly _disposables: IDisposable[] = []; + + constructor( + @IWorkspaceContextService private readonly _workspaceService: IWorkspaceContextService, + @IConfigurationService configService: IConfigurationService, + ) { + const config = BreadcrumbsConfig.FileExcludes.bindTo(configService); + const update = () => { + _workspaceService.getWorkspace().folders.forEach(folder => { + const excludesConfig = config.getValue({ resource: folder.uri }); + if (excludesConfig) { + this._cachedExpressions.set(folder.uri.toString(), glob.parse(excludesConfig)); + } + }); + }; + update(); + this._disposables.push( + config, + config.onDidChange(update), + _workspaceService.onDidChangeWorkspaceFolders(update) + ); + } + + dispose(): void { + dispose(this._disposables); + } + + isVisible(tree: ITree, element: IWorkspaceFolder | IFileStat): boolean { + if (IWorkspaceFolder.isIWorkspaceFolder(element)) { + // not a file + return true; + } + const folder = this._workspaceService.getWorkspaceFolder(element.resource); + if (!folder || !this._cachedExpressions.has(folder.uri.toString())) { + // no folder or no filer + return true; + } + + const expression = this._cachedExpressions.get(folder.uri.toString()); + return !expression(element.resource.path.substr(folder.uri.path.length), basename(element.resource)); + } +} + export class FileRenderer implements IRenderer, IHighlightingRenderer { private readonly _scores = new Map(); @@ -317,9 +366,13 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker { protected _completeTreeConfiguration(config: IHighlightingTreeConfiguration): IHighlightingTreeConfiguration { // todo@joh reuse explorer implementations? + const filter = this._instantiationService.createInstance(FileFilter); + this._disposables.push(filter); + config.dataSource = this._instantiationService.createInstance(FileDataSource); config.renderer = this._instantiationService.createInstance(FileRenderer); config.sorter = new FileSorter(); + config.filter = filter; return config; }