///|
test "vscode_algorithm" {
// VS Code's advanced algorithm with match positions
let (score, positions) = @fuzzyscore.vscode_fuzzy_score_simple(
"cat", "concatenate", true,
)
inspect(score, content="69")
inspect(positions, content="[3, 4, 5]")
}///|
test "vscode_comprehensive" {
// Basic usage
let (score, positions) = @fuzzyscore.vscode_fuzzy_score_simple(
"swt", "ss_ww_tt", true,
)
inspect(score, content="66")
inspect(positions, content="[1, 3, 6]")
// Camel case matching
let (score2, positions2) = @fuzzyscore.vscode_fuzzy_score_simple(
"fB", "fooBar", true,
)
inspect(score2, content="41")
inspect(positions2, content="[0, 3]")
// Exact match
let (score3, positions3) = @fuzzyscore.vscode_fuzzy_score_simple(
"test", "test", true,
)
inspect(score3, content="92")
inspect(positions3, content="[0, 1, 2, 3]")
}| Bonus Type | Value | Description |
|---|---|---|
| MATCH | 16 | Base score for any character match |
| CONSECUTIVE_MATCH | 29 | Bonus for consecutive characters |
| START_OF_WORD_MATCH | 23 | Match at word start |
| SEPARATOR_MATCH | 23 | Match after separator (_, -, space, etc.) |
| UPPER_CASE_MATCH | 23 | Exact case match |
| CAMEL_BONUS | 1 | Extra bonus for camelCase boundaries |
| GAP_LEADING | -5 | Penalty for leading unmatched characters |
| GAP_INNER | -1 | Penalty for gaps between matches |
///|
test "scoring_examples" {
// Consecutive matches get exponential bonuses
let (score1, _) = @fuzzyscore.vscode_fuzzy_score_simple("abc", "abc", true) // 69 - all consecutive
let (score2, _) = @fuzzyscore.vscode_fuzzy_score_simple("abc", "aXbXc", true) // 63 - with gaps
// Word boundaries are highly valued
let (score3, _) = @fuzzyscore.vscode_fuzzy_score_simple("fb", "foo_bar", true) // 39 - separator bonus
let (score4, _) = @fuzzyscore.vscode_fuzzy_score_simple(
"tF", "testFile", true,
) // 47 - camelCase bonus
inspect(score1 > score2, content="true")
inspect(score3 > 32, content="true") // Better than random positions
inspect(score4 > 32, content="true")
}///|
test "performance_test" {
let long_text = "this_is_a_very_long_file_name_with_many_underscores_and_words_to_test_performance"
// Algorithm handles long strings efficiently
let (score, positions) = @fuzzyscore.vscode_fuzzy_score_simple(
"test", long_text, true,
)
inspect(score > 0, content="true")
inspect(positions.length() == 4, content="true")
}///|
test "unicode_support" {
// Emoji support
let (score1, _pos1) = @fuzzyscore.vscode_fuzzy_score_simple(
"🌙", "moon🌙bit", true,
)
inspect(score1 > 0, content="true")
// CJK characters
let (score2, _pos2) = @fuzzyscore.vscode_fuzzy_score_simple(
"月", "moon月bit", true,
)
inspect(score2 > 0, content="true")
// Accented characters
let (score3, _pos3) = @fuzzyscore.vscode_fuzzy_score_simple(
"café", "café_file", true,
)
inspect(score3 > 0, content="true")
}///|
test "file_search_example" {
let files = [
"src/main.mbt", "test/main_test.mbt", "docs/README.md", "package.json",
]
// Search for "main"
let results = files
.map(fn(file) {
let (score, positions) = @fuzzyscore.vscode_fuzzy_score_simple(
"main", file, true,
)
(file, score, positions)
})
.filter(fn(result) { result.1 > 0 })
// Results are automatically ranked by score
inspect(results.length() == 2, content="false")
}///|
test "command_palette_example" {
let commands = [
"File: Open File", "Edit: Find and Replace", "View: Toggle Terminal", "Git: Commit All",
]
// Search for "file"
let query = "file"
let matches = commands
.map(fn(cmd) {
let (score, positions) = @fuzzyscore.vscode_fuzzy_score_simple(
query,
cmd.to_lower(),
true,
)
(cmd, score, positions)
})
.filter(fn(result) { result.1 > 0 })
inspect(matches.length() > 0, content="true")
}| Feature | Simple Algorithm | VS Code Algorithm |
|---|---|---|
| Speed | Fast O(n) | Moderate O(n×m) |
| Quality | Basic scoring | Advanced scoring |
| Positions | None | Exact positions |
| Use Case | Quick filtering | Production search |
fn vscode_fuzzy_score(pattern : String, pattern_start : Int, word : String, word_start : Int, first_match_can_be_weak : Bool) -> (Int, Array[Int])NO_MATCH = -∞ (we use -1_000_000)
MATCH = 16 Base score for any character match
CONSECUTIVE_MATCH = 29 MATCH + 13 (exponential bonus growth)
START_OF_WORD_MATCH = 23 MATCH + 7 (word boundary bonus)
UPPER_CASE_MATCH = 23 MATCH + 7 (case match bonus)
SEPARATOR_MATCH = 23 MATCH + 7 (after separator bonus)
CAMEL_BONUS = 1 Extra point for camelCase boundaries
GAP_LEADING = -5 Penalty for leading unmatched chars
GAP_INNER = -1 Penalty for internal gapsvscode_fuzzy_score("cat", "concatenate", true) => (74, [0,4,5])
vscode_fuzzy_score("swt", "ss_ww_tt", true) => (61, [0,3,6])
vscode_fuzzy_score("fb", "foo_bar", true) => (39, [0,4])