diff options
Diffstat (limited to 'lua/blink/cmp/sources/lib/queue.lua')
| -rw-r--r-- | lua/blink/cmp/sources/lib/queue.lua | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/lua/blink/cmp/sources/lib/queue.lua b/lua/blink/cmp/sources/lib/queue.lua new file mode 100644 index 0000000..3947902 --- /dev/null +++ b/lua/blink/cmp/sources/lib/queue.lua @@ -0,0 +1,68 @@ +local async = require('blink.cmp.lib.async') + +--- @class blink.cmp.SourcesQueue +--- @field id number +--- @field providers table<string, blink.cmp.SourceProvider> +--- @field request blink.cmp.Task | nil +--- @field queued_request_context blink.cmp.Context | nil +--- @field cached_items_by_provider table<string, blink.cmp.CompletionResponse> | nil +--- @field on_completions_callback fun(context: blink.cmp.Context, responses: table<string, blink.cmp.CompletionResponse>) +--- +--- @field new fun(context: blink.cmp.Context, providers: table<string, blink.cmp.SourceProvider>, on_completions_callback: fun(context: blink.cmp.Context, responses: table<string, blink.cmp.CompletionResponse>)): blink.cmp.SourcesQueue +--- @field get_cached_completions fun(self: blink.cmp.SourcesQueue): table<string, blink.cmp.CompletionResponse> | 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 |
