diff --git a/lua/cmp/core.lua b/lua/cmp/core.lua index a29526d..746a397 100644 --- a/lua/cmp/core.lua +++ b/lua/cmp/core.lua @@ -261,43 +261,54 @@ end ---Update completion menu core.filter = async.throttle( - vim.schedule_wrap(function(self) - self.filter.timeout = self.view:visible() and THROTTLE_TIME or 0 + setmetatable({ + ctx = nil, + }, { + __call = function(this, self) + self.filter.timeout = self.view:visible() and THROTTLE_TIME or 0 - local ignore = false - ignore = ignore or not api.is_suitable_mode() - if ignore then - return - end - - local sources = {} - for _, s in ipairs(self:get_sources({ source.SourceStatus.FETCHING, source.SourceStatus.COMPLETED })) do - if not s.incomplete and SOURCE_TIMEOUT > s:get_fetching_time() then - -- Reserve filter call for timeout. - self.filter.timeout = SOURCE_TIMEOUT - s:get_fetching_time() - self:filter() - break + -- Check context changed. + local ctx = self:get_context() + if this.ctx and not this.ctx:changed(ctx) then + return end - table.insert(sources, s) - end + this.ctx = ctx - local ctx = self:get_context() - - -- Display completion results. - self.view:open(ctx, sources) - - -- Check onetime config. - if #self:get_sources(function(s) - if s.status == source.SourceStatus.FETCHING then - return true - elseif #s:get_entries(ctx) > 0 then - return true + -- Check invalid condition. + local ignore = false + ignore = ignore or not api.is_suitable_mode() + if ignore then + return end - return false - end) == 0 then + + -- Check fetching sources. + local sources = {} + for _, s in ipairs(self:get_sources({ source.SourceStatus.FETCHING, source.SourceStatus.COMPLETED })) do + if not s.incomplete and SOURCE_TIMEOUT > s:get_fetching_time() then + -- Reserve filter call for timeout. + self.filter.timeout = SOURCE_TIMEOUT - s:get_fetching_time() + self:filter() + break + end + table.insert(sources, s) + end + + -- Display completion results. + self.view:open(ctx, sources) + + -- Check onetime config. + if #self:get_sources(function(s) + if s.status == source.SourceStatus.FETCHING then + return true + elseif #s:get_entries(ctx) > 0 then + return true + end + return false + end) == 0 then config.set_onetime({}) end - end), + end + }), THROTTLE_TIME ) diff --git a/lua/cmp/init.lua b/lua/cmp/init.lua index 6212ab8..16fff5c 100644 --- a/lua/cmp/init.lua +++ b/lua/cmp/init.lua @@ -67,11 +67,13 @@ end ---Get current selected entry or nil cmp.get_selected_entry = function() + cmp.core.filter.raw(cmp.core) return cmp.core.view:get_selected_entry() end ---Get current active entry or nil cmp.get_active_entry = function() + cmp.core.filter.raw(cmp.core) return cmp.core.view:get_active_entry() end diff --git a/lua/cmp/utils/async.lua b/lua/cmp/utils/async.lua index 39d8777..6746ba5 100644 --- a/lua/cmp/utils/async.lua +++ b/lua/cmp/utils/async.lua @@ -3,6 +3,7 @@ local async = {} ---@class cmp.AsyncThrottle ---@field public timeout number ---@field public stop function +---@field public raw function ---@field public __call function ---@param fn function @@ -12,11 +13,15 @@ async.throttle = function(fn, timeout) local time = nil local timer = vim.loop.new_timer() return setmetatable({ + running = false, timeout = timeout, stop = function() time = nil timer:stop() end, + raw = function(...) + fn(...) + end, }, { __call = function(self, ...) local args = { ... } @@ -28,8 +33,14 @@ async.throttle = function(fn, timeout) local delta = math.max(1, self.timeout - (vim.loop.now() - time)) timer:start(delta, 0, function() - time = nil - fn(unpack(args)) + if not self.running then + time = nil + self.running = true + vim.schedule(function() + self.running = false + fn(unpack(args)) + end) + end end) end, }) diff --git a/lua/cmp/view.lua b/lua/cmp/view.lua index c3a58e5..0eafcd2 100644 --- a/lua/cmp/view.lua +++ b/lua/cmp/view.lua @@ -198,7 +198,7 @@ end ---On entry change view.on_entry_change = async.throttle( - vim.schedule_wrap(function(self) + function(self) if not self:visible() then return end @@ -225,7 +225,7 @@ view.on_entry_change = async.throttle( else self.ghost_text_view:hide() end - end), + end, 20 )