Skip to content

Commit

Permalink
Update file-search to prioritize exact and better fuzzy matches
Browse files Browse the repository at this point in the history
Fixes #5636

- fixes an issue where better file results were not being displayed
by the file-search due to the limit. The limit meant that if we
ever reached the quota of results allowed some better results
were never to be displayed. Instead, the logic was changed so
that fuzzy matches are sorted by their score (how well they match
the `searchPattern`), then are sent to the front end limited by
the option. This means that all possible exact matches are sent
and the remaining best fuzzy matches along with them until the limit
is reached.

Signed-off-by: Vincent Fugnitto <vincent.fugnitto@ericsson.com>
  • Loading branch information
vince-fugnitto committed Jul 4, 2019
1 parent 37c9659 commit 6f431ce
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
10 changes: 10 additions & 0 deletions packages/file-search/src/node/file-search-service-impl.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@ describe('search-service', function () {
service = testContainer.get(FileSearchServiceImpl);
});

it('should find and prioritize exact file matches', async () => {
const pattern = 'file-search-service-impl';
const rootUri = FileUri.create(path.resolve(__dirname, '..')).toString();
const matches = await service.find(pattern, { rootUris: [rootUri] });
const expectedFile = FileUri.create(__filename).displayName;
const testFile = matches.find(e => e.endsWith(expectedFile));
expect(matches[0]).contains(pattern);
expect(testFile).to.be.not.undefined;
});

it('shall fuzzy search this spec file', async () => {
const rootUri = FileUri.create(path.resolve(__dirname, '..')).toString();
const matches = await service.find('spc', { rootUris: [rootUri] });
Expand Down
32 changes: 28 additions & 4 deletions packages/file-search/src/node/file-search-service-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ export class FileSearchServiceImpl implements FileSearchService {
} else if (opts.fuzzyMatch && fuzzy.test(searchPattern, candidate)) {
fuzzyMatches.add(fileUri);
}
if (exactMatches.size + fuzzyMatches.size === opts.limit) {
cancellationSource.cancel();
}
}, token);
} catch (e) {
console.error('Failed to search:', root, e);
Expand All @@ -96,7 +93,10 @@ export class FileSearchServiceImpl implements FileSearchService {
if (clientToken && clientToken.isCancellationRequested) {
return [];
}
return [...exactMatches, ...fuzzyMatches];
// Sort the fuzzy matches based on their score.
const sortedFuzzyMatches = Array.from(fuzzyMatches).sort((a: string, b: string) => this.compareFuzzyMatches(a, b, searchPattern));
// Return the limited list of exact and sorted matches.
return [...exactMatches, ...sortedFuzzyMatches].slice(0, opts.limit);
}

private doFind(rootUri: URI, options: FileSearchService.BaseOptions,
Expand Down Expand Up @@ -150,4 +150,28 @@ export class FileSearchServiceImpl implements FileSearchService {
return args;
}

/**
* Compare two fuzzy matches based on their score.
*
* @param a {string} comparison string.
* @param b {string} comparison string.
* @param searchPattern the search pattern to look for.
*/
private compareFuzzyMatches(a: string, b: string, searchPattern: string): number {
const scoreA: number = this.score(a, searchPattern);
const scoreB: number = this.score(b, searchPattern);
return scoreB - scoreA;
}

/**
* Score a given file uri against the `searchPattern`.
* @param uri {string} the file uri.
* @param searchPattern {string} the search pattern to look for.
*
* @returns the fuzzy match score.
*/
private score(uri: string, searchPattern: string): number {
const match = fuzzy.match(searchPattern, uri);
return (match === null) ? 0 : match.score;
}
}

0 comments on commit 6f431ce

Please sign in to comment.