@@ -40,7 +40,7 @@ import { ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/
4040import { URI } from 'vs/base/common/uri' ;
4141import { FileKind } from 'vs/platform/files/common/files' ;
4242import { 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' ;
4444import { IViewDescriptor , IViewDescriptorService } from 'vs/workbench/common/views' ;
4545import { localize } from 'vs/nls' ;
4646import { flatten , find } from 'vs/base/common/arrays' ;
@@ -77,6 +77,34 @@ import { ILabelService } from 'vs/platform/label/common/label';
7777
7878type 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+
80108interface 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
359391export 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