Skip to content

Commit cb1c577

Browse files
lszomorujoaomoreno
andauthored
SCM - Add support for filteting on the file path (microsoft#98235)
* Add support for filteting on the file path * Removed console.log * Update src/vs/workbench/contrib/scm/browser/repositoryPane.ts Co-authored-by: João Moreno <joao.moreno@microsoft.com> Co-authored-by: João Moreno <joao.moreno@microsoft.com>
1 parent 23e1fac commit cb1c577

2 files changed

Lines changed: 46 additions & 6 deletions

File tree

src/vs/workbench/browser/labels.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ class ResourceLabelWidget extends IconLabel {
505505
italic: this.options?.italic,
506506
strikethrough: this.options?.strikethrough,
507507
matches: this.options?.matches,
508+
descriptionMatches: this.options?.descriptionMatches,
508509
extraClasses: [],
509510
separator: this.options?.separator,
510511
domId: this.options?.domId

src/vs/workbench/contrib/scm/browser/repositoryPane.ts

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import { ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/
4040
import { URI } from 'vs/base/common/uri';
4141
import { FileKind } from 'vs/platform/files/common/files';
4242
import { compareFileNames } from 'vs/base/common/comparers';
43-
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
43+
import { FuzzyScore, createMatches, IMatch } from 'vs/base/common/filters';
4444
import { IViewDescriptor, IViewDescriptorService } from 'vs/workbench/common/views';
4545
import { localize } from 'vs/nls';
4646
import { flatten, find } from 'vs/base/common/arrays';
@@ -77,6 +77,34 @@ import { ILabelService } from 'vs/platform/label/common/label';
7777

7878
type TreeElement = ISCMResourceGroup | IResourceNode<ISCMResource, ISCMResourceGroup> | ISCMResource;
7979

80+
function splitMatches(uri: URI, filterData: FuzzyScore | undefined): [IMatch[] | undefined, IMatch[] | undefined] {
81+
let matches: IMatch[] | undefined;
82+
let descriptionMatches: IMatch[] | undefined;
83+
84+
if (filterData) {
85+
matches = [];
86+
descriptionMatches = [];
87+
88+
const fileName = basename(uri);
89+
const allMatches = createMatches(filterData);
90+
91+
for (const match of allMatches) {
92+
if (match.end <= fileName.length) {
93+
matches!.push(match);
94+
} else {
95+
descriptionMatches!.push(
96+
{
97+
start: match.start - fileName.length,
98+
end: match.end - fileName.length
99+
}
100+
);
101+
}
102+
}
103+
}
104+
105+
return [matches, descriptionMatches];
106+
}
107+
80108
interface ResourceGroupTemplate {
81109
readonly name: HTMLElement;
82110
readonly count: CountBadge;
@@ -188,7 +216,7 @@ class ResourceRenderer implements ICompressibleTreeRenderer<ISCMResource | IReso
188216
renderTemplate(container: HTMLElement): ResourceTemplate {
189217
const element = append(container, $('.resource'));
190218
const name = append(element, $('.name'));
191-
const fileLabel = this.labels.create(name, { supportHighlights: true });
219+
const fileLabel = this.labels.create(name, { supportDescriptionHighlights: true, supportHighlights: true });
192220
const actionsContainer = append(fileLabel.element, $('.actions'));
193221
const actionBar = new ActionBar(actionsContainer, {
194222
actionViewItemProvider: this.actionViewItemProvider,
@@ -214,11 +242,13 @@ class ResourceRenderer implements ICompressibleTreeRenderer<ISCMResource | IReso
214242
const fileKind = ResourceTree.isResourceNode(resourceOrFolder) ? FileKind.FOLDER : FileKind.FILE;
215243
const viewModel = this.viewModelProvider();
216244

245+
const [matches, descriptionMatches] = splitMatches(uri, node.filterData);
217246
template.fileLabel.setFile(uri, {
218247
fileDecorations: { colors: false, badges: !icon },
219248
hidePath: viewModel.mode === ViewModelMode.Tree,
220249
fileKind,
221-
matches: createMatches(node.filterData)
250+
matches,
251+
descriptionMatches
222252
});
223253

224254
template.actionBar.clear();
@@ -270,10 +300,12 @@ class ResourceRenderer implements ICompressibleTreeRenderer<ISCMResource | IReso
270300
const label = compressed.elements.map(e => e.name).join('/');
271301
const fileKind = FileKind.FOLDER;
272302

303+
const [matches, descriptionMatches] = splitMatches(folder.uri, node.filterData);
273304
template.fileLabel.setResource({ resource: folder.uri, name: label }, {
274305
fileDecorations: { colors: false, badges: true },
275306
fileKind,
276-
matches: createMatches(node.filterData)
307+
matches,
308+
descriptionMatches
277309
});
278310

279311
template.actionBar.clear();
@@ -358,13 +390,20 @@ export class SCMTreeSorter implements ITreeSorter<TreeElement> {
358390

359391
export class SCMTreeKeyboardNavigationLabelProvider implements ICompressibleKeyboardNavigationLabelProvider<TreeElement> {
360392

393+
constructor(@ILabelService private readonly labelService: ILabelService) { }
394+
361395
getKeyboardNavigationLabel(element: TreeElement): { toString(): string; } | undefined {
362396
if (ResourceTree.isResourceNode(element)) {
363397
return element.name;
364398
} else if (isSCMResourceGroup(element)) {
365399
return element.label;
366400
} else {
367-
return basename(element.sourceUri);
401+
// Since a match in the file name takes precedence over a match
402+
// in the folder name we are returning the label as file/folder.
403+
const fileName = basename(element.sourceUri);
404+
const filePath = this.labelService.getUriLabel(dirname(element.sourceUri), { relative: true });
405+
406+
return filePath.length !== 0 ? `${fileName}${filePath}` : fileName;
368407
}
369408
}
370409

@@ -877,7 +916,7 @@ export class RepositoryPane extends ViewPane {
877916

878917
const filter = new SCMTreeFilter();
879918
const sorter = new SCMTreeSorter(() => this.viewModel);
880-
const keyboardNavigationLabelProvider = new SCMTreeKeyboardNavigationLabelProvider();
919+
const keyboardNavigationLabelProvider = this.instantiationService.createInstance(SCMTreeKeyboardNavigationLabelProvider);
881920
const identityProvider = new SCMResourceIdentityProvider();
882921

883922
this.tree = this.instantiationService.createInstance(

0 commit comments

Comments
 (0)