Saghen / blink.cmp

Performant, batteries-included completion plugin for Neovim
MIT License
631 stars 26 forks source link

nvim-cmp source provider #80

Open stefanboca opened 9 hours ago

stefanboca commented 9 hours ago

This PR adds a provider that acts as a compatibility layer for nvim-cmp sources, as well as some api endpoints from nvim-cmp that sources commonly use.

The way to use a nvim-cmp source is by using the blink.cmp.sources.compat.nvim_cmp provider with a name field equal to the name of the nvim-cmp source. For cmp-path, this would be

{
  "blink.cmp.sources.compat.nvim_cmp,
  name = "path",
}

I've made this PR a draft because it is a somewhat large change. Additionally, this is only a minimal implementation that will probably not yet work for more complicated sources. So far, I've only minimally tested cmp-path and crates.nvim.

A (non-exhaustive) list of work that still needs to be done:

I welcome any feedback or suggestions you may have.

Thank you!

stefanboca commented 5 hours ago

I'd be happy to continue working on this in a separate repo. Having a separate repo also has the added benefit of having the ability to release separately from blink.cmp itself, ex. in the case nvim-cmp makes a breaking change to its source API.

As I understand it, currently the only control providers have over the trigger level is by providing a list of characters to trigger on [^1], while we currently have a global keyword_regex that controls a "global" trigger. Is there any plan to have a per-provider keyword_regex?

entry_filter should be trivial to implement [^2]. The only issue I was facing is that currently, providers do not have (easy) access to their SourceProviderConfig. Is it possible, instead of passing opts and name to each provider, to pass the config directly? I believe this is also required for other parts of this compatibility layer. For instance, the parameters passed to source:complete should be an expansion of this table.

Is nvim-cmp's source:resolve equivalent to our source:resolve? If so, the implementation should be fairly simple.

Lastly, source:execute is a nvim-cmp function in their source spec that is called after a completion is selected. I do not currently see an equivalent to this. Is this possible to implement?

[^1] Unrelated: if only some providers have a given trigger character, do just those providers trigger on that character, or all providers?

[^2] In nvim-cmp, entry_filter is defined in their equivalent of SourceProviderConfig - I.E. directly by the user. This is not necessarily related directly to nvim-cmp sources, so maybe it is better to more generally implement this directly in blink.cmp.sources.lib.source? That would also allow users of this plugin to write custom filters for any source, and the implementation would probably map better to our async model.