diff --git a/lua/cmp/source.lua b/lua/cmp/source.lua index ba16b77..87a95a8 100644 --- a/lua/cmp/source.lua +++ b/lua/cmp/source.lua @@ -18,6 +18,7 @@ local char = require('cmp.utils.char') ---@field public incomplete boolean ---@field public is_triggered_by_symbol boolean ---@field public entries cmp.Entry[] +---@field public filtered {entries: cmp.Entry[], ctx: cmp.Context} ---@field public offset integer ---@field public request_offset integer ---@field public context cmp.Context @@ -53,6 +54,7 @@ source.reset = function(self) self.is_triggered_by_symbol = false self.incomplete = false self.entries = {} + self.filtered = {} self.offset = -1 self.request_offset = -1 self.completion_context = nil @@ -88,6 +90,10 @@ source.get_entries = function(self, ctx) return {} end + if self.filtered.ctx and self.filtered.ctx.id == ctx.id then + return self.filtered.entries + end + local target_entries = (function() local key = { 'get_entries', self.revision } for i = ctx.cursor.col, self.offset, -1 do @@ -103,7 +109,9 @@ source.get_entries = function(self, ctx) local entry_filter = self:get_entry_filter() local inputs = {} + ---@type cmp.Entry[] local entries = {} + local max_item_count = self:get_source_config().max_item_count or 200 local matching_config = self:get_matching_config() for _, e in ipairs(target_entries) do local o = e:get_offset() @@ -119,21 +127,22 @@ source.get_entries = function(self, ctx) e.exact = e:get_filter_text() == inputs[o] or e:get_word() == inputs[o] if entry_filter(e, ctx) then - table.insert(entries, e) + entries[#entries + 1] = e + if max_item_count and #entries >= max_item_count then + break + end end end end - self.cache:set({ 'get_entries', tostring(self.revision), ctx.cursor_before_line }, entries) - local max_item_count = self:get_source_config().max_item_count or 200 - 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 + -- only save to cache, when there are no additional entries that could match the filter + -- This also prevents too much memory usage + if #entries < max_item_count then + self.cache:set({ 'get_entries', tostring(self.revision), ctx.cursor_before_line }, entries) end - return limited_entries + + self.filtered = { entries = entries, ctx = ctx } + return entries end ---Get default insert range (UTF8 byte index).