Just recording some observations I found.
Problem:
When a user sets cot=fuzzy, the completion candidates are not collected based on fuzzy criteria. As a result, the completion menu can miss items. For example, typing f and triggering completion will not show xfoo as a candidate.
This behavior is inconsistent with VSCode and other modern IDEs. Additionally, the resulting list was not sorted (this is fixed by #18497).
Currently, to make fuzzy completion work correctly, a user has to know about the obscure completefuzzycollect option and set it to keyword. This is unnecessary and confusing. End users generally don’t care about the difference between “collection” vs “filtering”; exposing this implementation detail results in poor UX.
Proposed solution:
If a user sets cot=fuzzy, then always:
Examples:
:set cot=fuzzy → fuzzy collect + fuzzy sort.:set cot=longest,fuzzy → fuzzy collect + fuzzy sort, but compute longest only from matches whose prefix matches the typed text. All matches are shown. (This mirrors the current behavior when :set completefuzzycollect=keyword.)Note: In the
longest,fuzzycase, computinglongestfrom a subset of visible matches may feel a little unintuitive. This just needs to be documented.
Relevant discussion: #15295, which led to the current design.
Instructions: Replace the template text and remove irrelevant text (including this line)
Is your feature request about something that is currently impossible or hard to do? Please describe the problem.
A clear and concise description of what is hard to do. Ex. It is difficult to [...] when [...]
(If it is related to runtime files, please check their header for where to discuss enhancements.)
Describe the solution you'd like
A clear and concise description of what you want to happen.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I don't have any particular strong opinion here and it wouldn't be too late to retire the completefuzzycollect option, if everybody agrees that the completefuzzycollect option is not particular useful. So let me ping a few folks from the previous discussion @ychin @habamax @glepnir @roccomao
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
I support removal of that setting, if enabled, fuzzy should work for both collection and filtering.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I remember it was introduced because some users needed to disable fuzzy matching for certain patterns. It doesn’t really affect me, so let’s first evaluate the user’s needs
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
In #16434 (comment) I proposed some expectation of sort, pasted here:
For example, for ac pattern
ac
actor
factor
bracket
match
malloc
would be the expected order. Not sure where ancient should be (below actor, bracket or somewhere else).
Now it is possible with cfc+=keyword and cot+=fuzzy,longest.
It would be good to still can enforce such order, but I didn't find it very usable, because it is limited to few sources.
I used keyword completion there, but only to keep the example as simple as possible, not realizing that the solution might depend on the sources.
It seems I didn't understand at that moment and still don't understand when a results list is or can be sorted, especially when it is expanded by complete-functions logic. Even as a (Nvim) user I still feel confused by the complexity of the completion logic (extended by possible bugs) and if there are related things possible only in Nvim. The below (probably multi-issue) example shows unsorted result the final list after extending by omnifunc:
fun! s:add(base) let results = ['acer', 'account', 'ace', 'vim']->filter({idx, val -> val =~ '^' .. a:base}) "call complete(1, results) for res in results call complete_add(res) endfor endfun fun! Omni(findstart, base) if a:findstart return endif call timer_start(1000, { -> s:add(a:base) }) " it seems that s:add is called immediately endfun call setline(1, ['actor', 'match', 'ac', 'malloc', 'factor', 'bracket', '']) normal G set omnifunc=Omni set complete=.,o " even if `ac` present we need `<C-n>` to see the omnifunc results set ac acl=300 completeopt=menuone,noinsert,fuzzy startinsert
Side note: currently ac seems to implicitly enforce cfc.
Finally, I'm also open to experiment described in the initial post. Anyway, thanks for @glepnir for the existing approach.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
New algorithm does it:
image.png (view on web)without completefuzzycollect=keyword though you will not get the candidates at all.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Even as a (Nvim) user I still feel confused ...
And for the nvim users, they can still use the completefuzzycollect by not merging the change if @chrisbra would agree to remove the option.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I will admit I don't use fuzzy much so maybe I'm not the target audience and I don't have real stakes in this but I do echo the sentiment that this whole "fuzzy collect" vs "fuzzy filtering" concept is just too much. I don't really like that it's a concept exposed to the user as I still find the current myriad of fuzzy-related options really confusing just to understand. You shouldn't need intimate knowledge with the internal workings for Vim to be able to configure fuzzy matching properly. Complexity always has a cost, even for a software like Vim that's designed to be configurable (maybe especially when it's Vim?) I haven't really kept up to date with the new fuzzy algorithm that went in to Vim recently though.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
So if the current implementation causes issues anyhow, I fine with retiring the option. It comes from f31cfa2 which I commited in march, so that is 7 months ago. Github search shows it's used in about 115 Vim Script files. So it might be acceptable to be retired.
@dkearns @zeertzjq @yegappan would you mind if we remove it completely?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
so what would you suggest then? I only hear critics, make some constructive suggestions please
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
keep cfc, and if ok then impl t and i of cpt for cfc=key word would be better.
okay that is a suggestion.
that 2ed vim dev policy, if going to revert, in maximal 1 week.
I have said that before, that is not possible, sometimes we only notice much later that a change is problematic. Restricting ourselves to 1 week to revert issues, would be very problematic.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@chrisbra I don't think you should have to put up with this persons constant rudeness, just kick them.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
We can mark it as deprecated if you think it will break someone’s workflow.
Removing it in the end would be a good thing.
However, I would suggest to just remove it. Fuzzy should not be over complicated.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Thank you @nickspoons I started feeling a bit uncomfortable here. @Shane-XB-Qian I don't want to lock anybody out here, but there have been some "misunderstandings" in the past. Let me blame it on the foreign language. But please try to watch your tone in the future.
Getting back to the topic. @girishji would marking it as deprecating help (and potentially being a noop)?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
So if the current implementation causes issues anyhow, I fine with retiring the option. It comes from f31cfa2 which I commited in march, so that is 7 months ago. Github search shows it's used in about 115 Vim Script files. So it might be acceptable to be retired.
@dkearns @zeertzjq @yegappan would you mind if we remove it completely?
No. I agree with the earlier comment that the 'completefuzzycollect' option is obscure and will be confusing to users. It makes sense to remove this option and rely only on the 'completeopt' option value.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@nickspoons, 100% agree. Nuking that Shane-XB troll would instantly restore sanity anywhere he shows up. The guy’s basically a human !operator — just negate whatever he says and you’re golden. Besides, he’s clearly unhinged. Allowing him to keep derailing threads unchecked isn’t moderation; it’s cruelty to everyone else trying to get real work done.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
@chrisbra I believe now you have enough information to make a decision on option removal.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
please donot each time bring it to political or manner level,
Putting "tech opinions" aside, your comments are very rude, and this is not the first time. If you are unfamiliar with polite English, you could ask a chatbot (ChatGPT, Qwen, whatever) to rewrite your comment before posting it. Please don't give open-source contributors more stress.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
We can mark it as deprecated if you think it will break someone’s workflow.
- Note it is deprecated in the relevant help topic
- make it no-op, so configs are not broken with option no exists error.
- remove it after some time, before 9.2
Removing it in the end would be a good thing.
However, I would suggest to just remove it. Fuzzy should not be over complicated.
If you want to mark it as deprecated I think we should do something more than making it silently do nothing. Otherwise someone who has set it in their vimc will never find out that it's deprecated unless they randomly browse the docs and see that. Then they will still be surprised somewhere down the line, just delayed from the actual deprecation. Why bother doing the deprecation work then? May as well just straight up remove it now, or commit to keeping a dummy do-nothing option in the foreseeable future. You can use official point releases (e.g. v9.2) as a marker for doing backwards compatible changes but I'm not sure if Vim's versioning history has historically established that it uses semantic versioning in such ways, nor will users who grab Vim via a package manager notice.
With proper deprecation I would imagine you should at least throw a warning message when this is set so someone can see that their configs is now deprecated. I feel like this is also how compilers handling deprecated APIs usually work. (FWIW if you are just setting a setting in vimrc using set cfc=blah, currently a non-existent option is just going to barf out an error but Vimscript will keep parsing. It's only in situations like Vim9script where a non-existent option really causes an issue)
Another example is that in Git, there is a very old command called git whatchanged. They have been trying to remove it for a while now and every time someone runs that it will print out a message saying that it's deprecated, and you can add a flag (--i-still-use-this) to force it to succeed, and/or email the Git mailing list for advice what to do instead (which is to use git log with some extra flags).
I was also thinking: when was the last time we removed user-visible option like this? Last I remember was Bram removing cmdheight=0 ~2 months after the feature went in. (a2a8973) That one also received a bit of pushback, but it was also objectively a more popular feature given that it's much more visible to a user.
I do think this should be the exception, and not the norm. If we find ourselves consistently reverting changes (even just now we have #18618 which proposes modifying a user-visible behavior that's been around for half a year), I think the development process is not working correctly and needs to be addressed.
@Shane-XB-Qian There's a reason why everyone is calling you out for being rude. It's not like we don't understand your concerns, but going hardline, pushing a my-way-or-highway, and using condescending languages isn't going to help you convince folks, especially considering you are not the maintainer. Ultimately open source is a collaborative effort and the project isn't always going to make decisions that you agree with. It's up to you if you want to engage.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
i donot think there is a "everyone", but funny some guys kept to jump in to such topic, it was nothing related to political or manner.
Because your manner is too much more noticeable than your "technical idea".
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@ychin I agree that it would be nice to introduce deprecation path for the things that might not be relevant anymore or things that would be nice to get rid of at some point.
That was just a compromise suggestion as I still believe it is not too late to remove that option (it was introduced to workaround not quite good enough fuzzy algorithm, which is now not the case)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
For my workflow, I like the current &completefuzzycollect situation (though I'd be fine with any combination of options that lets me do prefix-only matching for collection, and fuzzy candidate completion).
Generally, I use only two or three characters of an identifier prefix to start completion, and then use '&cot=fuzzy' to whittle them down. If &cfc includes keyword, then the candidate list is full of identifiers I didn't intend.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
For my workflow, I like the current
&completefuzzycollectsituation (though I'd be fine with any combination of options that lets me do prefix-only matching for collection, and fuzzy candidate completion).Generally, I use only two or three characters of an identifier prefix to start completion, and then use '&cot=fuzzy' to whittle them down. If
&cfcincludeskeyword, then the candidate list is full of identifiers I didn't intend.
With the new fuzzy algorithm and instant sorting, your workflow will be fine. You can skip completefuzzycollect.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
👋 Howdy folks. Some of you might know me from around here or previously moderating https://vi.stackexchange.com
If you would, allow me a moment of your time to share a lesson or two from that experience.
@chrisbra I seem to have something to say about this every so often—would you be interested in a dedicated thread on community moderation for the Vim project? It's not unusual for projects to grow large enough that they need policy and/or contributors to engage with such a topic and help things grow in the direction the community agrees makes sense.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
This would impact dictionary autocomplete, as completefuzzycollect breaks infercase, you wont be able to complete words at the start of sentences (unless they're proper nouns) with set ac cpt=k cot+=fuzzy ic inf if fuzzy collection is enforced.
Not that this is an argument against removing the option, but rather a thing that should probably be fixed before/if it is.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
This would impact dictionary autocomplete, as
completefuzzycollectbreaksinfercase, you wont be able to complete words at the start of sentences (unless they're proper nouns) withset ac cpt=k cot+=fuzzy ic infif fuzzy collection is enforced.Not that this is an argument against removing the option, but rather a thing that should probably be fixed before/if it is.
Can you provide an example of how completefuzzyccollect helps complete words at the beginning of a sentence?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
@Shane-XB-Qian this is my last warning, sorry, but next time you will get suspended for 3 months.
@benknoble Yes, I believe we need a some community guidelines. I'll see what I can propose in the next days.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Folks, I appreciate your input.
So how about this then: we mark it as deprecated and echo a message (perhaps only once?) when the option is being used. I'll also remove it from version9.txt when the change to mark this option as deprecated is being merged. After the Vim 9.2 point release we will remove the option completely.
I do think this should be the exception, and not the norm. If we find ourselves consistently reverting changes (even just now we have #18618 which proposes modifying a user-visible behavior that's been around for half a year), I think the development process is not working correctly and needs to be addressed.
Yeah, this seems to indicate that our development process is improvable. But not sure how to improve it. Back then it seems like a good idea...
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
But not sure how to improve it.
This may be the nuclear option and unacceptable for historical reasons, but one solution would be to stop "releasing" each individual commit as a tagged version and only consider the 9.x bumps as "real" releases. This would give you much more headroom for iterating on features without having to worry about backward compatibility (since distros will package anything with a version number that is not fast enough to get away).
(You can still have 9.x.y bugfix releases, although that would require keeping a separate branch to backport to.)
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Can you provide an example of how completefuzzyccollect helps complete words at the beginning of a sentence?
@girishji here's an example, suppose you have a dictionary containing one word: hello, doing i_CTRL-X_CTRL-K will give you the following:
With set infercase ignorecase:
h -> hello
H -> Hello
HE -> HELLO
With set completefuzzycollect+=keyword infercase ignorecase:
h -> hello
H -> {nothing}
HE -> {nothing}
And so if set completeopt+=fuzzy were to enforce fuzzy collection you would lose the ability to complete most capitalised words with set ac complete=k, for now at least.
Note that for manual ins-completion you can work around this with a simple mapping.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
But not sure how to improve it.
This may be the nuclear option and unacceptable for historical reasons, but one solution would be to stop "releasing" each individual commit as a tagged version and only consider the 9.x bumps as "real" releases. This would give you much more headroom for iterating on features without having to worry about backward compatibility on every commit (since distros will package anything with a version number that is not fast enough to get away).
I'd of course still be interested in running the latest tip of master, which some distributions support anyway (e.g., Gentoo), so this seems viable.
It would also allow for a potentially workflow that potentially requires less of Christian (e.g., removing the patch bump on every single commit). Dropping that is quite a large change and has ramifications for things like has(), I think, so would probably need more thought?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Of course you'd still want people to use master in order to get testing and feedback, but as you note that's no problem (many distros have "head/tip" packages, and you can also put "nightly" builds on the Github release). The important point here is to make a clear distinction between a "safe" release and a "caveat emptor, things may break" WIP development build.
Regarding has(), that would still work but be (much) more granular -- which may be a good thing ("this is new in Vim 9.2" is easier to communicate than "you need Vim 9.1.1338 or later").
But, yes, this would be a big change, and up the maintainers to consider whether it'd be a net positive given Vim's project goals.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Can you provide an example of how completefuzzyccollect helps complete words at the beginning of a sentence?
@girishji here's an example, suppose you have a dictionary containing one word:
hello, doingi_CTRL-X_CTRL-Kwill give you the following:With
set infercase ignorecase:h -> hello H -> Hello HE -> HELLOWith
set completefuzzycollect+=keyword infercase ignorecase:h -> hello H -> {nothing} HE -> {nothing}
And so, for now at least, if
set completeopt+=fuzzywas to enforce fuzzy collection you would lose the ability to complete most capitalised words withset ac complete=k.
Note that for manual ins-completion you can work around this with a simple mapping.
This is a peculiar behavior coming from infercase. In both cases (with or without fuzzy) hello is being collected. You can file this as a bug. This needs to be addressed separately.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
[snip]
But, yes, this would be a big change, and up the maintainers to consider whether it'd be a net positive given Vim's project goals.
I think you and I are thinking along the same lines here :) great to see!
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
This may be the nuclear option and unacceptable for historical reasons, but one solution would be to stop "releasing" each individual commit as a tagged version and only consider the 9.x bumps as "real" releases. This would give you much more headroom for iterating on features without having to worry about backward compatibility on every commit (since distros will package anything with a version number that is not fast enough to get away).
I think that's fine for a long term goal (the lack of a stable release has been the bane of my life in terms of picking a "good" release for shipping MacVim releases), but it needs to be synchronized with how people actually use and download Vim. Right now, the point releases are so far and few in between (years apart) that anyone who wants to use a remotely recent Vim (including security fixes) would need to use patch releases. 9.1.0000 is almost 2 years old now. That's why package managers just grab the latest Vim and call it a day. E.g. I just checked Homebrew and they are on 9.1.1850 which is pretty recent. It would probably require us to have a more clearly defined release schedule and policy regarding what each release means, and how feature stability works; and make sure package managers etc follow these release cycles. If the "real" releases are too far and few between you could end up with features taking years before they make their way to users' hands, or people just ignore the "real" releases and just grab from master.
There's also a question to exactly what a "real" release means. Is it just in terms of backwards compatibility, the way semantic versioning work? What about stability? Personally one thing that I really don't want is that this becomes an implicit permission to break master because "it's only dev anyway".
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
I was looking into this when I noticed #18756 , thanks for fixing this!
So would this do what you expect?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
I was looking into this when I noticed #18756 , thanks for fixing this!
So would this do what you expect?
There’s a bug that needs to be addressed: #18498 (comment)
When ignorecase is set, the collection should either be done non-fuzzily, or the fuzzy matching algorithm should itself ignore case. I’m not sure whether additional issues arise when infercase is enabled--this will require some testing.
Aside from that, the change looks good. Eventually, perhaps in a separate commit, all of the unnecessary code should be removed.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
When
ignorecaseis set, the collection should either be done non-fuzzily, or the fuzzy matching algorithm should itself ignore case.
I believe when fuzzy is set, ignorecase should be ignored as it does now.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
When
ignorecaseis set, the collection should either be done non-fuzzily, or the fuzzy matching algorithm should itself ignore case.I believe when fuzzy is set, ignorecase should be ignored as it does now.
Can we change this? Right now, if the pattern starts with an uppercase letter, lowercase matches are excluded. I think we should include lowercase matches as well.
The fzy algorithm already matches case-insensitively and then scores based on camelCase and uppercase boundaries.
fzy currently treats all searches as case-insensitive. However, scoring prefers matches on
uppercase letters to help find CamelCase candidates.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
It does seem more consistent to me for ignorecase and smartcase to be respected as much as possible, though I notice that only a few items in :help ins-completion specifically state that these options apply.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
It does seem more consistent to me for ignorecase and smartcase to be respected as much as possible, though I notice that only a few items in
:help ins-completionspecifically state that these options apply.
I’m considering treating fuzzy matching purely as a scoring mechanism--assuming there’s some correlation between the pattern and the word--while ensuring that other filters (such as ignorecase and smartcase) influence only the sorting of results rather than excluding items from the menu altogether. This feels intuitive, since fuzzy matching would naturally take priority over case-related filters if we think of these options as a hierarchy of filtering layers.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Can we change this? Right now, if the pattern starts with an uppercase letter, lowercase matches are excluded. I think we should include lowercase matches as well.
oh, I almost never start a pattern with an uppercase and yes, this would have been nice to include lowercase matches as well.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Closed #18498 as completed via 33fbfe0.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()