Implement source specific options

This commit is contained in:
hrsh7th
2021-09-03 20:30:40 +09:00
parent 45b96b212c
commit 889109cbc0
4 changed files with 64 additions and 22 deletions

View File

@@ -193,7 +193,7 @@ mapping = {
} }
``` ```
#### sources (type: table<string>) #### sources (type: table<cmp.SourceConfig>)
Globals source lists are listed in the `source` table. These are applied to all 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 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) example look at the [hrsh7th/cmp-buffer](https://github.com/hrsh7th/cmp-buffer)
source README which defines the source name as `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[]) #### completion.autocomplete (type: cmp.TriggerEvent[])
Which events should trigger `autocompletion`. Which events should trigger `autocompletion`.

View File

@@ -40,20 +40,20 @@ config.get = function()
end) end)
end end
---Return source option ---Return source config
---@param name string ---@param name string
---@return table ---@return cmp.SourceConfig
config.get_source_option = function(name) config.get_source_config = function(name)
local global = config.global local global = config.global
local buffer = config.buffers[vim.api.nvim_get_current_buf()] or { revision = 1 } 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() return config.cache:ensure({ 'get_source_config', global.revision or 0, buffer.revision or 0, name }, function()
local c = config.get() local c = config.get()
for _, s in ipairs(c.sources) do for _, s in ipairs(c.sources) do
if s.name == name then if s.name == name then
if type(s.opts) == 'table' then if type(s.opts) ~= 'table' then
return s.opts s.opts = {}
end end
return {} return s
end end
end end
return nil return nil

View File

@@ -62,15 +62,9 @@ source.reset = function(self)
end end
---Return source option ---Return source option
---@return table ---@return cmp.SourceConfig
source.get_option = function(self) source.get_config = function(self)
return config.get_source_option(self.name) return config.get_source_config(self.name)
end
---Return the source has items or not.
---@return boolean
source.has_items = function(self)
return self.offset ~= -1
end end
---Get fetching time ---Get fetching time
@@ -85,7 +79,7 @@ end
---@param ctx cmp.Context ---@param ctx cmp.Context
---@return cmp.Entry[] ---@return cmp.Entry[]
source.get_entries = function(self, ctx) source.get_entries = function(self, ctx)
if not self:has_items() then if self.offset == -1 then
return {} return {}
end end
@@ -101,7 +95,7 @@ source.get_entries = function(self, ctx)
return nil return nil
end)() 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)) debug.log(self:get_debug_name(), 'filter', #(prev_entries or self.entries))
local inputs = {} local inputs = {}
@@ -118,8 +112,19 @@ source.get_entries = function(self, ctx)
table.insert(entries, e) table.insert(entries, e)
end end
end end
return entries return entries
end) 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 end
---Get default insert range ---Get default insert range
@@ -185,21 +190,35 @@ end
---Get keyword_pattern ---Get keyword_pattern
---@return string ---@return string
source.get_keyword_pattern = function(self) 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 if self.source.get_keyword_pattern then
return self.source:get_keyword_pattern({ return self.source:get_keyword_pattern({
option = self:get_option(), option = self:get_config().opts,
}) })
end end
return config.get().completion.keyword_pattern return config.get().completion.keyword_pattern
end 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 ---Get trigger_characters
---@return string[] ---@return string[]
source.get_trigger_characters = function(self) source.get_trigger_characters = function(self)
local trigger_characters = {} local trigger_characters = {}
if self.source.get_trigger_characters then if self.source.get_trigger_characters then
trigger_characters = self.source:get_trigger_characters({ trigger_characters = self.source:get_trigger_characters({
option = self:get_option(), option = self:get_config().opts,
}) or {} }) or {}
end end
if config.get().completion.get_trigger_characters then if config.get().completion.get_trigger_characters then
@@ -247,7 +266,7 @@ source.complete = function(self, ctx, callback)
triggerCharacter = before_char_iw, triggerCharacter = before_char_iw,
} }
elseif ctx:get_reason() ~= types.cmp.ContextReason.TriggerOnly then 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 if self.incomplete and self.context.cursor.col ~= ctx.cursor.col then
completion_context = { completion_context = {
triggerKind = types.lsp.CompletionTriggerKind.TriggerForIncompleteCompletions, triggerKind = types.lsp.CompletionTriggerKind.TriggerForIncompleteCompletions,
@@ -285,7 +304,7 @@ source.complete = function(self, ctx, callback)
{ {
context = ctx, context = ctx,
offset = self.offset, offset = self.offset,
option = self:get_option(), option = self:get_config().opts,
completion_context = completion_context, completion_context = completion_context,
}, },
self.complete_dedup(vim.schedule_wrap(function(response) self.complete_dedup(vim.schedule_wrap(function(response)

View File

@@ -95,6 +95,9 @@ cmp.PreselectMode.None = 'none'
---@class cmp.SourceConfig ---@class cmp.SourceConfig
---@field public name string ---@field public name string
---@field public opts table ---@field public opts table
---@field public keyword_pattern string
---@field public keyword_length number
---@field public max_item_count number
return cmp return cmp