nvim-cmp icon indicating copy to clipboard operation
nvim-cmp copied to clipboard

feat: add `filter` option to sources

Open jonatan-branting opened this issue 1 year ago • 3 comments

This allows the user to specify a filter function for each source.

Solves: https://github.com/hrsh7th/nvim-cmp/issues/1036 https://github.com/hrsh7th/nvim-cmp/issues/1041 https://github.com/hrsh7th/nvim-cmp/issues/806

@hrsh7th do you see any problems with this implementation or approach in general?

An example:

-- don't show entries with kind "Text" from the "nvim_lsp" source
sources = {
{
  name = "nvim_lsp",
  filter = function(entry, ctx)
    local kind = types.lsp.CompletionItemKind[entry:get_kind()]

    if kind == "Text" then return true end
  },
}

By utilizing the ctx parameter, the user can also ignore certain entries in certain contexts.

Notes:

  • The name filter might not be entirely clear; what does returning true or false actually result in? Ideas?
  • Documentation has to be added.
  • Specs have to be added. There doesn't seem to be a precedence for testing other configuration options, not sure it's entirely necessary either.

jonatan-branting avatar Jul 07 '22 16:07 jonatan-branting

As a user, I think this feature is useful. I have luasnip and some LSP servers also provide snippets. It is annoying that LSP's snippets are always standing before the luasnip's but the quality of them is not so good. I know how to adjust their priority, but a filter function provides great scalability.

Weissle avatar Jul 23 '22 13:07 Weissle

Yes. This feature is useful. I'm thinking about the API design...

hrsh7th avatar Jul 24 '22 03:07 hrsh7th

Usually, in filter functions, when you return true that means you want the item, if you don't want the item, you return false .

Massolari avatar Aug 03 '22 20:08 Massolari

I pushed some updates according to feedback (03a7a91). If anyone used my fork then this will have broken your configuration, sorry about that! @kkharji and @bennypowers

Noteworthy changes:

  • filter -> entry_filter
  • Returning true keeps the entry, returning false removes it it.

jonatan-branting avatar Aug 11 '22 13:08 jonatan-branting

@hrsh7th if this is good enough for you I'll add documentation and we can maybe get this merged? :)

jonatan-branting avatar Aug 11 '22 13:08 jonatan-branting

What about the document? @hrsh7th may not merge this PR without the document updated.

Weissle avatar Aug 13 '22 01:08 Weissle

What about the document? @hrsh7th may not merge this PR without the document updated.

I'm holding off on that until I get the OK from @hrsh7th whether or not this is the solution he wants to go for or not.

jonatan-branting avatar Aug 13 '22 11:08 jonatan-branting

I thought it would be more versatile to add an override option to the source and add the ability to override all source functions. As shown below.

{
  name = 'buffer',
  override = {
    complete = function(source_complete, params, callback)
      source_complete(params, function(response))
        -- modify complete response from source.
        callback(modify(response))
      end)
    end
  }
}

However, this API is too advanced. Therefore, I can accept this feature.

Translated with www.DeepL.com/Translator (free version)

hrsh7th avatar Aug 20 '22 10:08 hrsh7th

Please update the docs.

hrsh7th avatar Aug 20 '22 10:08 hrsh7th

Please update the docs.

I'll most likely be able to get this done tomorrow :)

jonatan-branting avatar Aug 21 '22 21:08 jonatan-branting

@hrsh7th I've added documentation, let me know if there is anything you want me to change!

jonatan-branting avatar Aug 23 '22 10:08 jonatan-branting

add this to line 155 in lua/types/cmp.lua

---@field public entry_filter nil|(function(entry: cmp.Entry, ctx: cmp.Context): boolean)

full block:

---@class cmp.SourceConfig
---@field public name string
---@field public option table|nil
---@field public priority integer|nil
---@field public trigger_characters string[]|nil
---@field public keyword_pattern string|nil
---@field public keyword_length integer|nil
---@field public max_item_count integer|nil
---@field public group_index integer|nil
---@field public entry_filter nil|(function(entry: cmp.Entry, ctx: cmp.Context): boolean)

bennypowers avatar Aug 23 '22 11:08 bennypowers

Could you take a look? This featue have been backlogged for two monthes. @hrsh7th

Weissle avatar Aug 28 '22 01:08 Weissle

LGTM. Thank you.

hrsh7th avatar Sep 08 '22 03:09 hrsh7th