From 889109cbc046584330463c315573c74a38f7711e Mon Sep 17 00:00:00 2001 From: hrsh7th Date: Fri, 3 Sep 2021 20:30:40 +0900 Subject: [PATCH] Implement source specific options --- README.md | 22 ++++++++++++++++++- lua/cmp/config.lua | 12 +++++------ lua/cmp/source.lua | 49 ++++++++++++++++++++++++++++++------------- lua/cmp/types/cmp.lua | 3 +++ 4 files changed, 64 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index e156963..9f02baf 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ mapping = { } ``` -#### sources (type: table) +#### sources (type: table) Globals source lists are listed in the `source` table. These are applied to all buffers. The order of the sources list helps define the source priority, see @@ -218,6 +218,26 @@ Source names are defined in the source repository README files. For example look at the [hrsh7th/cmp-buffer](https://github.com/hrsh7th/cmp-buffer) source README which defines the source name as `buffer`. +#### sources[number].name (type: string) + +The source name. + +#### sources[number].opts (type: table) + +The source customization options. It is defined by each source. + +#### sources[number].keyword_pattern (type: string) + +The source specific keyword_pattern for override. + +#### sources[number].keyword_length (type: number) + +The source specific keyword_length for override. + +#### sources[number].max_item_count (type: number) + +The source specific maximum item count. + #### completion.autocomplete (type: cmp.TriggerEvent[]) Which events should trigger `autocompletion`. diff --git a/lua/cmp/config.lua b/lua/cmp/config.lua index 0a78227..c6c87b7 100644 --- a/lua/cmp/config.lua +++ b/lua/cmp/config.lua @@ -40,20 +40,20 @@ config.get = function() end) end ----Return source option +---Return source config ---@param name string ----@return table -config.get_source_option = function(name) +---@return cmp.SourceConfig +config.get_source_config = function(name) local global = config.global local buffer = config.buffers[vim.api.nvim_get_current_buf()] or { revision = 1 } return config.cache:ensure({ 'get_source_config', global.revision or 0, buffer.revision or 0, name }, function() local c = config.get() for _, s in ipairs(c.sources) do if s.name == name then - if type(s.opts) == 'table' then - return s.opts + if type(s.opts) ~= 'table' then + s.opts = {} end - return {} + return s end end return nil diff --git a/lua/cmp/source.lua b/lua/cmp/source.lua index 3d84dc3..c2a06f4 100644 --- a/lua/cmp/source.lua +++ b/lua/cmp/source.lua @@ -62,15 +62,9 @@ source.reset = function(self) end ---Return source option ----@return table -source.get_option = function(self) - return config.get_source_option(self.name) -end - ----Return the source has items or not. ----@return boolean -source.has_items = function(self) - return self.offset ~= -1 +---@return cmp.SourceConfig +source.get_config = function(self) + return config.get_source_config(self.name) end ---Get fetching time @@ -85,7 +79,7 @@ end ---@param ctx cmp.Context ---@return cmp.Entry[] source.get_entries = function(self, ctx) - if not self:has_items() then + if self.offset == -1 then return {} end @@ -101,7 +95,7 @@ source.get_entries = function(self, ctx) return nil end)() - return self.cache:ensure({ 'get_entries', self.revision, ctx.cursor_before_line }, function() + local entries = self.cache:ensure({ 'get_entries', self.revision, ctx.cursor_before_line }, function() debug.log(self:get_debug_name(), 'filter', #(prev_entries or self.entries)) local inputs = {} @@ -118,8 +112,19 @@ source.get_entries = function(self, ctx) table.insert(entries, e) end end + return entries end) + + local max_item_count = self:get_config().max_item_count + local limited_entries = {} + for _, e in ipairs(entries) do + table.insert(limited_entries, e) + if max_item_count and #limited_entries >= max_item_count then + break + end + end + return limited_entries end ---Get default insert range @@ -185,21 +190,35 @@ end ---Get keyword_pattern ---@return string source.get_keyword_pattern = function(self) + local c = self:get_config() + if c.keyword_pattern then + return c.keyword_pattern + end if self.source.get_keyword_pattern then return self.source:get_keyword_pattern({ - option = self:get_option(), + option = self:get_config().opts, }) end return config.get().completion.keyword_pattern end +---Get keyword_length +---@return number +source.get_keyword_length = function(self) + local c = self:get_config() + if c.keyword_length then + return c.keyword_length + end + return config.get().completion.keyword_length or 1 +end + ---Get trigger_characters ---@return string[] source.get_trigger_characters = function(self) local trigger_characters = {} if self.source.get_trigger_characters then trigger_characters = self.source:get_trigger_characters({ - option = self:get_option(), + option = self:get_config().opts, }) or {} end if config.get().completion.get_trigger_characters then @@ -247,7 +266,7 @@ source.complete = function(self, ctx, callback) triggerCharacter = before_char_iw, } elseif ctx:get_reason() ~= types.cmp.ContextReason.TriggerOnly then - if config.get().completion.keyword_length <= (ctx.cursor.col - offset) then + if self:get_keyword_length() <= (ctx.cursor.col - offset) then if self.incomplete and self.context.cursor.col ~= ctx.cursor.col then completion_context = { triggerKind = types.lsp.CompletionTriggerKind.TriggerForIncompleteCompletions, @@ -285,7 +304,7 @@ source.complete = function(self, ctx, callback) { context = ctx, offset = self.offset, - option = self:get_option(), + option = self:get_config().opts, completion_context = completion_context, }, self.complete_dedup(vim.schedule_wrap(function(response) diff --git a/lua/cmp/types/cmp.lua b/lua/cmp/types/cmp.lua index d013849..3b250b6 100644 --- a/lua/cmp/types/cmp.lua +++ b/lua/cmp/types/cmp.lua @@ -95,6 +95,9 @@ cmp.PreselectMode.None = 'none' ---@class cmp.SourceConfig ---@field public name string ---@field public opts table +---@field public keyword_pattern string +---@field public keyword_length number +---@field public max_item_count number return cmp