diff --git a/src/vs/base/common/filters.ts b/src/vs/base/common/filters.ts index 688488529f26b..ed5d856458528 100644 --- a/src/vs/base/common/filters.ts +++ b/src/vs/base/common/filters.ts @@ -577,21 +577,20 @@ export function fuzzyScore(pattern: string, word: string): [number, number[]] { function findAllMatches(patternLen: number, patternPos: number, wordPos: number, total: number, matches: number[], bucket: [number, number[]][]): void { + let lastMatched = false; + while (patternPos > 0 && wordPos > 0) { - let value = _table[patternPos][wordPos]; + let score = _scores[patternPos][wordPos]; let arrow = _arrows[patternPos][wordPos]; if (arrow === Arrow.Left || score < 0) { // left wordPos -= 1; - - } else if (arrow === Arrow.Diag) { - // diag - total += value; - patternPos -= 1; - wordPos -= 1; - matches.unshift(wordPos); + if (lastMatched) { + total -= 5; // gap penalty + } + lastMatched = false; } else if (arrow & Arrow.Diag) { @@ -601,10 +600,11 @@ function findAllMatches(patternLen: number, patternPos: number, wordPos: number, } // diag - total += value; + total += score; patternPos -= 1; wordPos -= 1; matches.unshift(wordPos); + lastMatched = true; } else { return undefined; diff --git a/src/vs/base/test/common/filters.test.ts b/src/vs/base/test/common/filters.test.ts index e1fd42d7d72f5..15f8433add393 100644 --- a/src/vs/base/test/common/filters.test.ts +++ b/src/vs/base/test/common/filters.test.ts @@ -224,6 +224,13 @@ suite('Filters', () => { assertMatches('c:\\do', '& \'c:\\Documents and Settings\'', '& \'^c^:^\\^D^ocuments and Settings\'', fuzzyScore); }); + test('fuzzyScore, #23581', function () { + assertMatches('close', 'css.lint.importStatement', '^css.^lint.imp^ort^Stat^ement', fuzzyScore); + assertMatches('close', 'css.colorDecorators.enable', '^css.co^l^orDecorator^s.^enable', fuzzyScore); + assertMatches('close', 'workbench.quickOpen.closeOnFocusOut', 'workbench.quickOpen.^c^l^o^s^eOnFocusOut', fuzzyScore); + assertTopScore(fuzzyScore, 'close', 2, 'css.lint.importStatement', 'css.colorDecorators.enable', 'workbench.quickOpen.closeOnFocusOut'); + }); + test('fuzzyScore', function () { assertMatches('ab', 'abA', '^a^bA', fuzzyScore); assertMatches('ccm', 'cacmelCase', '^ca^c^melCase', fuzzyScore); @@ -277,7 +284,7 @@ suite('Filters', () => { }); function assertTopScore(filter: typeof fuzzyScore, pattern: string, expected: number, ...words: string[]) { - let topScore = -Number.MIN_VALUE; + let topScore = -(100 * 10); let topIdx = 0; for (let i = 0; i < words.length; i++) { const word = words[i]; diff --git a/src/vs/editor/contrib/suggest/common/completionModel.ts b/src/vs/editor/contrib/suggest/common/completionModel.ts index 70e4908c0c9e5..b611b449e5aa6 100644 --- a/src/vs/editor/contrib/suggest/common/completionModel.ts +++ b/src/vs/editor/contrib/suggest/common/completionModel.ts @@ -105,7 +105,7 @@ export class CompletionModel { const { leadingLineContent, characterCountDelta } = this._lineContext; let word = ''; - let topScore = -Number.MIN_VALUE; + let topScore = -(100 * 10); for (const item of this._items) {