diff --git a/src/util/filter.ts b/src/util/filter.ts index ba206aecce6..2d3d379bd4a 100644 --- a/src/util/filter.ts +++ b/src/util/filter.ts @@ -81,21 +81,46 @@ function fuzzyScoreWithPermutations(pattern: string, lowPattern: string, pattern // permutations of the pattern to find a better match. The // permutations only swap neighbouring characters, e.g // `cnoso` becomes `conso`, `cnsoo`, `cnoos`. - const tries = Math.min(7, pattern.length - 1) - for (let movingPatternPos = patternPos + 1; movingPatternPos < tries; movingPatternPos++) { - const newPattern = nextTypoPermutation(pattern, movingPatternPos) + // + // For the last 2 permutations try to remove the last characters, + // maybe the last few letters are typos. For example, + // `conson` could be a typo for `console` + const maxTriesPermutation = Math.min(7, pattern.length - 1); + + // Loop for existing permutations + for (let i = 1; i <= maxTriesPermutation; i++) { + const newPattern = nextTypoPermutation(pattern, patternPos + i); + checkAndUpdateTopCandidate(newPattern, 3); + } + + const lastChar = pattern.charAt(pattern.length - 1); + + if (/[a-zA-Z0-9]/.test(lastChar)) { + // Loop for removing characters at all positions + for (let i = 0; i < pattern.length; i++) { + const newPattern = pattern.slice(0, i) + pattern.slice(i + 1); + checkAndUpdateTopCandidate(newPattern, 4); + } + + // Loop for removing last characters + for (let i = 1; i < 3; i++) { + const newPattern = pattern.slice(0, pattern.length - i); + checkAndUpdateTopCandidate(newPattern, i + 4); + } + } + + function checkAndUpdateTopCandidate(newPattern: string, penalty: number) { if (newPattern) { - const candidate = fuzzyScore(newPattern, newPattern.toLowerCase(), patternPos, word, lowWord, wordPos, options) + const candidate = fuzzyScore(newPattern, newPattern.toLowerCase(), patternPos, word, lowWord, wordPos, options); if (candidate) { - candidate[0] -= 3 // permutation penalty + candidate[0] -= penalty; // permutation penalty if (!top || candidate[0] > top[0]) { - top = candidate + top = candidate; } } } } } - return top }