Repository navigation
Fuzzy matching prioritizes internal match to prefix match #17531
Description
Activity
Try to turn off camelcase option, however would only work for a function.
Reacted by Lifepillarsee #16797
It would be nice to have CamelCase prioritization turned off for command-line complete...
Reacted by LifepillarOh, I missed that patch back then 9dfc7e5
Without camelcase preference enhancement it was more predictable and natural. :(
Just a thought... If we are too late to revert CamelCase prioritization, maybe we can have extended
fuzzysettings:set completeopt+=fuzzy:nocamel set wildoptions+=fuzzy:nocamel?
What’s the correct scoring approach for matching?
Would the following be a good solution?
- If the search pattern contains an uppercase letter, then case-sensitive matches should receive a score boost; otherwise, case-sensitive matches could be penalized slightly.
- If the match occurs at the start of the string, it should also receive a higher score.
Regarding the "camel case" option — it feels unnecessary or unintuitive. A well-designed scoring algorithm should naturally account for uppercase letters and camelCase structure without requiring a separate option.
Regarding the "camel case" option — it feels unnecessary or unintuitive. A well-designed scoring algorithm should naturally account for uppercase letters and camelCase structure without requiring a separate option.
I agree, however last try to tinker with it wasn't quite successful #16797
Looks like it is already supposed to do what I proposed:
Line 4294 in 4829511
* Fuzzy string matching
Maybe some more tweaking is needed.There is also this algorithm: https://github.com/junegunn/fzf/blob/master/src/algo/algo.go
maybe the patch that introduced enhanced camelcase could be tweaked?
I wonder if reverting is an option, @chrisbra ?
Hmm, I guess it wouldn't be that simple/easy to do.
I wonder if reverting is an option, @chrisbra ?
Hmm, I guess it wouldn't be that simple/easy to do.
I'll take a closer look when I get a chance. Based on the algorithm's description, it should have handled all those basic cases—including camelCase—without requiring such significant "tweaks".
Reacted by Maxim Kimsee also #17581
I've looked into this — the current fuzzy matching algorithm isn't very accurate. It struggles with CamelCase and often fails to prioritize matches at the beginning of a string over those in the middle. You can see this in action on the author's own demo app (type into the box): reverse_engineering_sublime_texts_fuzzy_match/
The original author clearly optimized for performance over accuracy, and I suspect whoever integrated this into Vim was aware of that tradeoff.
Fuzzy scoring is inherently heuristic-based and imprecise. Accuracy and performance are often at odds, and this algorithm leans heavily toward performance.
The PRs from the author you mentioned introduced regressions (e.g., this issue and #17576) likely because he/she misunderstood the limitations and tradeoffs of the existing algorithm. Those "tweaks" are a net-negative.
If the project is interested in improving fuzzy search, there are several better alternatives:
-
fzy – A relatively simple C implementation with ~3k GitHub stars. MIT license. It can act as a drop-in replacement.
- https://github.com/jhawthorn/fzy
- Algorithm description: https://github.com/jhawthorn/fzy/blob/master/ALGORITHM.md
-
VSCode – A more sophisticated algorithm written in TypeScript, but portable to C. It features richer scoring.
Both account for non-contiguous matches, case sensitivity, CamelCase, and word boundaries. I have not tested them for performance, but given the reputation I assume they made the right tradeoffs.
Other options worth noting:
- fuse.js (JS)
- fuzzysort (JS)
- fast-fuzzy(JS)
- fzf (Go)
-
I (for myself) would love to see improvements here (specifically see how fzy algorithm would fit vim).
1 remaining item
Sounds good!
I like the idea of "drop-in replacement" taking an advantage of using existing established project's code. But ultimately it will depend on @chrisbra and the team to choose "better fit" implementation.
implemented essentially the same algorithm (modulo details)
17581 implementation of the full three-matrix gaps simthwaterman fzf uses a single matrix. I have used fzy in telescope but I have not read the details of its algorithm. helix uses 2 matrices. fuzzy completion in helix works well.
- added a commit that references this issue
on Aug 12, 2025 - added 6 commits that reference this issue
on Aug 13, 2025 - added a commit that references this issue
on Aug 23, 2025 - added a commit that references this issue
on Sep 7, 2025 - added a commit that references this issue
on Sep 27, 2025
Steps to reproduce
Execute:
The output is
['BindTerminal', 'terminal']. Or, in the command line:vim --cleanset wildoptions=fuzzy:command BindTerminal :<cr>:trm<TAB>The command line is expanded to
BindTerminal. This behaviour has started with patch v9.1.1046.Expected behaviour
In the examples above, I would expect that
terminalis the first match, as it matches a prefix of the text (case-sensitively, btw).Even ignoring the position of the match,
termortrmis intuitively “more similar” (e.g., in terms of edit distance) toterminalthan toBindTerminal.Version of Vim
9.1.1455
Environment
macOS
Apple Terminal
xterm-256color
ZSH 5.9
Logs and stack traces