summaryrefslogtreecommitdiff
path: root/mut/neovim/pack/plugins/start/blink.cmp/lua/blink/cmp/sources/lib/queue.lua
blob: 394790204ff32c2a9f15424d8a2b272d1b2da183 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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