Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix strange behavior of files.exclude in workspace with nested folders #118777

Merged
merged 2 commits into from
Mar 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/vs/workbench/contrib/files/browser/explorerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> {
if (!this.view) {
return;
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/contrib/files/browser/files.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void>;
setToCopy(stats: ExplorerItem[], cut: boolean): Promise<void>;
isCut(stat: ExplorerItem): boolean;
Expand Down
6 changes: 2 additions & 4 deletions src/vs/workbench/contrib/files/browser/views/explorerView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -719,7 +717,7 @@ export class ExplorerView extends ViewPane {
item = child;
break;
}
item = undefined;
item = null;
}
}

Expand Down
45 changes: 19 additions & 26 deletions src/vs/workbench/contrib/files/browser/views/explorerViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ExplorerItem, FuzzyScore> {
private hiddenExpressionPerRoot: Map<string, CachedParsedExpression>;
private uriVisibilityMap = new Map<URI, boolean>();
private hiddenExpressionPerRoot = new Map<string, CachedParsedExpression>();
private editorsAffectingFilter = new Set<IEditorInput>();
private _onDidChange = new Emitter<void>();
private toDispose: IDisposable[] = [];
Expand All @@ -545,7 +544,6 @@ export class FilesFilter implements ITreeFilter<ExplorerItem, FuzzyScore> {
@IEditorService private readonly editorService: IEditorService,
@IUriIdentityService private readonly uriIdentityService: IUriIdentityService
) {
this.hiddenExpressionPerRoot = new Map<string, CachedParsedExpression>();
this.toDispose.push(this.contextService.onDidChangeWorkspaceFolders(() => this.updateConfiguration()));
this.toDispose.push(this.configurationService.onDidChangeConfiguration((e) => {
if (e.affectsConfiguration('files.exclude')) {
Expand All @@ -555,26 +553,30 @@ export class FilesFilter implements ITreeFilter<ExplorerItem, FuzzyScore> {
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();
}
}));
Expand Down Expand Up @@ -603,21 +605,12 @@ export class FilesFilter implements ITreeFilter<ExplorerItem, FuzzyScore> {

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 {
Expand All @@ -636,7 +629,7 @@ export class FilesFilter implements ITreeFilter<ExplorerItem, FuzzyScore> {
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
}
Expand Down