local async = require('blink.cmp.lib.async') --- @class blink.cmp.SourcesQueue --- @field id number --- @field providers table --- @field request blink.cmp.Task | nil --- @field queued_request_context blink.cmp.Context | nil --- @field cached_items_by_provider table | nil --- @field on_completions_callback fun(context: blink.cmp.Context, responses: table) --- --- @field new fun(context: blink.cmp.Context, providers: table, on_completions_callback: fun(context: blink.cmp.Context, responses: table)): blink.cmp.SourcesQueue --- @field get_cached_completions fun(self: blink.cmp.SourcesQueue): table | nil --- @field get_completions fun(self: blink.cmp.SourcesQueue, context: blink.cmp.Context) --- @field destroy fun(self: blink.cmp.SourcesQueue) --- @type blink.cmp.SourcesQueue --- @diagnostic disable-next-line: missing-fields local queue = {} function queue.new(context, providers, on_completions_callback) local self = setmetatable({}, { __index = queue }) self.id = context.id self.providers = providers self.request = nil self.queued_request_context = nil self.on_completions_callback = on_completions_callback return self end function queue:get_cached_completions() return self.cached_items_by_provider end function queue:get_completions(context) assert(context.id == self.id, 'Requested completions on a sources context with a different context ID') if self.request ~= nil then if self.request.status == async.STATUS.RUNNING then self.queued_request_context = context return else self.request:cancel() end end -- Create a task to get the completions, send responses upstream -- and run the queued request, if it exists local tree = require('blink.cmp.sources.lib.tree').new(context, vim.tbl_values(self.providers)) self.request = tree:get_completions(context, function(items_by_provider) self.cached_items_by_provider = items_by_provider self.on_completions_callback(context, items_by_provider) -- run the queued request, if it exists local queued_context = self.queued_request_context if queued_context ~= nil then self.queued_request_context = nil self.request:cancel() self:get_completions(queued_context) end end) end function queue:destroy() self.on_completions_callback = function() end if self.request ~= nil then self.request:cancel() end end return queue