From 913eb8599816b0b71fe959693080917d8063b26a Mon Sep 17 00:00:00 2001 From: Jonatan Branting Date: Thu, 8 Sep 2022 05:48:27 +0200 Subject: [PATCH] feat: add `filter` option to sources (#1067) * feat: add `source.filter` config This allows the user to specify a `filter` function for each source, like this: ```lua -- 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. * fixup! feat: add `source.filter` config * fixup! feat: add `source.filter` config --- doc/cmp.txt | 25 +++++++++++++++++++++++++ lua/cmp/source.lua | 17 ++++++++++++++++- lua/cmp/types/cmp.lua | 1 + 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/doc/cmp.txt b/doc/cmp.txt index 17fbf89..19b421a 100644 --- a/doc/cmp.txt +++ b/doc/cmp.txt @@ -560,6 +560,31 @@ sources[n].group_index~ }) } < + + *cmp-config.sources[n].entry_filter* +sources[n].entry_filter~ + `function` + A source-specific entry filter, with the following function signature: +> + function(entry: cmp.Entry, ctx: cmp.Context): boolean +< + + Returning `true` will keep the entry, while returning `false` will remove it. + + This can be used to hide certain entries from a given source. For instance, you + could hide all entries with kind `Text` from the `nvim_lsp` filter using the + following source definition: +> + { + name = 'nvim_lsp', + entry_filter = function(entry, ctx) + return require('cmp.types').lsp.CompletionItemKind[entry:get_kind()] ~= 'Text' + end + } +< + Using the `ctx` parameter, you can further customize the behaviour of the + source. + *cmp-config.view* view~ `{ entries: cmp.EntriesConfig|string }` diff --git a/lua/cmp/source.lua b/lua/cmp/source.lua index f081642..9a364ec 100644 --- a/lua/cmp/source.lua +++ b/lua/cmp/source.lua @@ -101,6 +101,8 @@ source.get_entries = function(self, ctx) return self.entries end)() + local entry_filter = self:get_entry_filter() + local inputs = {} local entries = {} for _, e in ipairs(target_entries) do @@ -115,7 +117,10 @@ source.get_entries = function(self, ctx) if e.score >= 1 then e.matches = match.matches e.exact = e:get_filter_text() == inputs[o] or e:get_word() == inputs[o] - table.insert(entries, e) + + if entry_filter(e, ctx) then + table.insert(entries, e) + end end end self.cache:set({ 'get_entries', self.revision, ctx.cursor_before_line }, entries) @@ -232,6 +237,16 @@ source.get_keyword_length = function(self) return config.get().completion.keyword_length or 1 end +---Get filter +--@return function +source.get_entry_filter = function(self) + local c = self:get_source_config() + if c.entry_filter then + return c.entry_filter + end + return function(_, _) return true end +end + ---Invoke completion ---@param ctx cmp.Context ---@param callback function diff --git a/lua/cmp/types/cmp.lua b/lua/cmp/types/cmp.lua index 451b83c..1e33f22 100644 --- a/lua/cmp/types/cmp.lua +++ b/lua/cmp/types/cmp.lua @@ -152,6 +152,7 @@ cmp.ItemField = { ---@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 ---@class cmp.ViewConfig ---@field public entries cmp.EntriesConfig