diff --git a/src/vs/workbench/contrib/files/browser/explorerService.ts b/src/vs/workbench/contrib/files/browser/explorerService.ts index bda2583ddfdab..b7e7fd2d5915c 100644 --- a/src/vs/workbench/contrib/files/browser/explorerService.ts +++ b/src/vs/workbench/contrib/files/browser/explorerService.ts @@ -170,6 +170,12 @@ export class ExplorerService implements IExplorerService { return this.model.findClosest(resource); } + findClosestRoot(resource: URI): ExplorerItem | null { + const parentRoots = this.model.roots.filter(r => this.uriIdentityService.extUri.isEqualOrParent(resource, r.resource)) + .sort((first, second) => second.resource.path.length - first.resource.path.length); + return parentRoots.length ? parentRoots[0] : null; + } + async setEditable(stat: ExplorerItem, data: IEditableData | null): Promise { if (!this.view) { return; diff --git a/src/vs/workbench/contrib/files/browser/files.ts b/src/vs/workbench/contrib/files/browser/files.ts index 2dc5b638d224e..9594446078e2e 100644 --- a/src/vs/workbench/contrib/files/browser/files.ts +++ b/src/vs/workbench/contrib/files/browser/files.ts @@ -84,6 +84,7 @@ export interface IExplorerService { // If undefined is passed checks if any element is currently being edited. isEditable(stat: ExplorerItem | undefined): boolean; findClosest(resource: URI): ExplorerItem | null; + findClosestRoot(resource: URI): ExplorerItem | null; refresh(): Promise; setToCopy(stats: ExplorerItem[], cut: boolean): Promise; isCut(stat: ExplorerItem): boolean; diff --git a/src/vs/workbench/contrib/files/browser/views/explorerView.ts b/src/vs/workbench/contrib/files/browser/views/explorerView.ts index 9d370daf3c563..05f26f13526b7 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerView.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerView.ts @@ -703,9 +703,7 @@ export class ExplorerView extends ViewPane { } // Expand all stats in the parent chain. - let item: ExplorerItem | undefined = this.explorerService.roots.filter(i => this.uriIdentityService.extUri.isEqualOrParent(resource, i.resource)) - // Take the root that is the closest to the stat #72299 - .sort((first, second) => second.resource.path.length - first.resource.path.length)[0]; + let item: ExplorerItem | null = this.explorerService.findClosestRoot(resource); while (item && item.resource.toString() !== resource.toString()) { try { @@ -719,7 +717,7 @@ export class ExplorerView extends ViewPane { item = child; break; } - item = undefined; + item = null; } } diff --git a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts index e4368479dd8bc..8c8b29d819abd 100644 --- a/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/contrib/files/browser/views/explorerViewer.ts @@ -532,8 +532,7 @@ interface CachedParsedExpression { * Makes sure that visible editors are always shown in the explorer even if they are filtered out by settings. */ export class FilesFilter implements ITreeFilter { - private hiddenExpressionPerRoot: Map; - private uriVisibilityMap = new Map(); + private hiddenExpressionPerRoot = new Map(); private editorsAffectingFilter = new Set(); private _onDidChange = new Emitter(); private toDispose: IDisposable[] = []; @@ -545,7 +544,6 @@ export class FilesFilter implements ITreeFilter { @IEditorService private readonly editorService: IEditorService, @IUriIdentityService private readonly uriIdentityService: IUriIdentityService ) { - this.hiddenExpressionPerRoot = new Map(); this.toDispose.push(this.contextService.onDidChangeWorkspaceFolders(() => this.updateConfiguration())); this.toDispose.push(this.configurationService.onDidChangeConfiguration((e) => { if (e.affectsConfiguration('files.exclude')) { @@ -555,26 +553,30 @@ export class FilesFilter implements ITreeFilter { this.toDispose.push(this.editorService.onDidVisibleEditorsChange(() => { const editors = this.editorService.visibleEditors; let shouldFire = false; - this.uriVisibilityMap.forEach((visible, uri) => { - if (!visible) { - editors.forEach(e => { - if (e.resource && this.uriIdentityService.extUri.isEqualOrParent(e.resource, uri)) { - // A filtered resource suddenly became visible since user opened an editor - shouldFire = true; - } - }); + + for (const e of editors) { + if (!e.resource) { + continue; } - }); - this.editorsAffectingFilter.forEach(e => { + const stat = this.explorerService.findClosest(e.resource); + if (stat && stat.isExcluded) { + // A filtered resource suddenly became visible since user opened an editor + shouldFire = true; + break; + } + } + + for (const e of this.editorsAffectingFilter) { if (!editors.includes(e)) { // Editor that was affecting filtering is no longer visible shouldFire = true; + break; } - }); + } + if (shouldFire) { this.editorsAffectingFilter.clear(); - this.uriVisibilityMap.clear(); this._onDidChange.fire(); } })); @@ -603,21 +605,12 @@ export class FilesFilter implements ITreeFilter { if (shouldFire) { this.editorsAffectingFilter.clear(); - this.uriVisibilityMap.clear(); this._onDidChange.fire(); } } filter(stat: ExplorerItem, parentVisibility: TreeVisibility): boolean { - const cachedVisibility = this.uriVisibilityMap.get(stat.resource); - if (typeof cachedVisibility === 'boolean') { - return cachedVisibility; - } - - const isVisible = this.isVisible(stat, parentVisibility); - this.uriVisibilityMap.set(stat.resource, isVisible); - - return isVisible; + return this.isVisible(stat, parentVisibility); } private isVisible(stat: ExplorerItem, parentVisibility: TreeVisibility): boolean { @@ -636,7 +629,7 @@ export class FilesFilter implements ITreeFilter { stat.isExcluded = true; const editors = this.editorService.visibleEditors; const editor = editors.find(e => e.resource && this.uriIdentityService.extUri.isEqualOrParent(e.resource, stat.resource)); - if (editor) { + if (editor && stat.root === this.explorerService.findClosestRoot(stat.resource)) { this.editorsAffectingFilter.add(editor); return true; // Show all opened files and their parents }