diff --git a/src/vs/base/common/fuzzyScorer.ts b/src/vs/base/common/fuzzyScorer.ts index 413a6115dd20f30f96ada59bf77fae637a904aa7..a961f2c5cf9ba22907baecda0bea61f1143c07bd 100644 --- a/src/vs/base/common/fuzzyScorer.ts +++ b/src/vs/base/common/fuzzyScorer.ts @@ -526,15 +526,45 @@ function createMatches(offsets: number[] | undefined): IMatch[] { } function normalizeMatches(matches: IMatch[]): IMatch[] { - const positions = new Set(); - for (const match of matches) { - for (let i = match.start; i < match.end; i++) { - positions.add(i); + // sort matches by start to be able to normalize + const sortedMatches = matches.sort((matchA, matchB) => { + return matchA.start - matchB.start; + }); + + // merge matches that overlap + const normalizedMatches: IMatch[] = []; + let currentMatch: IMatch | undefined = undefined; + for (const match of sortedMatches) { + + // if we have no current match or the matches + // do not overlap, we take it as is and remember + // it for future merging + if (!currentMatch || !matchOverlaps(currentMatch, match)) { + currentMatch = match; + normalizedMatches.push(match); } + + // otherwise we merge the matches + else { + currentMatch.start = Math.min(currentMatch.start, match.start); + currentMatch.end = Math.max(currentMatch.end, match.end); + } + } + + return normalizedMatches; +} + +function matchOverlaps(matchA: IMatch, matchB: IMatch): boolean { + if (matchA.end < matchB.start) { + return false; // A ends before B starts + } + + if (matchB.end < matchA.start) { + return false; // B ends before A starts } - return createMatches(Array.from(positions.values()).sort((a, b) => a - b)); + return true; } //#endregion