Skip to content
Closed
40 changes: 33 additions & 7 deletions src/util/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,47 @@ 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);
const maxTries = maxTriesPermutation + pattern.length;
Comment thread
fannheyward marked this conversation as resolved.
Outdated

// Loop for existing permutations
Comment thread
fannheyward marked this conversation as resolved.
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))) {
Comment thread
fannheyward marked this conversation as resolved.
Outdated
// Loop for removing characters at all positions
for (let i = 0; i < pattern.length; i++) {
Comment thread
fannheyward marked this conversation as resolved.
const newPattern = pattern.slice(0, i) + pattern.slice(i + 1);
checkAndUpdateTopCandidate(newPattern, 4);
}

Comment thread
fannheyward marked this conversation as resolved.
// Loop for removing last characters
for (let i = 1; i < 3; i++) {
const newPattern = pattern.slice(0, pattern.length - i);
checkAndUpdateTopCandidate(newPattern, i+4);

Copilot AI Nov 27, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The penalty system is inconsistent and potentially incorrect:

  • Character permutations (line 94): penalty of 3
  • Removing any character at any position (line 103): penalty of 4
  • Removing last 1 character (line 109 when i=1): penalty of 5
  • Removing last 2 characters (line 109 when i=2): penalty of 6

This means removing the last character has a higher penalty (5) than removing a character in the middle (4), which seems counterintuitive since typos at the end are more common than in the middle. Consider revising the penalty structure to be more logical, for example:

  • Permutations: 3
  • Remove last 1 char: 4
  • Remove last 2 chars: 5
  • Remove middle chars: 6 (higher penalty since less likely to be a typo)
Suggested change
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);
// Penalty 6 for removing middle chars (less likely typo)
checkAndUpdateTopCandidate(newPattern, 6);
}
// Loop for removing last characters
for (let i = 1; i < 3; i++) {
// Penalty 4 for last char, 5 for last two chars
checkAndUpdateTopCandidate(newPattern, i + 3);

Copilot uses AI. Check for mistakes.
Comment thread
fannheyward marked this conversation as resolved.
Outdated
}
Comment thread
fannheyward marked this conversation as resolved.
}

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
}

Expand Down