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
69
70
71
72
73
74
|
local async = require('blink.cmp.lib.async')
local known_defaults = {
'commitCharacters',
'insertTextFormat',
'insertTextMode',
'data',
}
local CompletionTriggerKind = vim.lsp.protocol.CompletionTriggerKind
local completion = {}
--- @param context blink.cmp.Context
--- @param client vim.lsp.Client
--- @return blink.cmp.Task
function completion.get_completion_for_client(context, client)
return async.task.new(function(resolve)
local params = vim.lsp.util.make_position_params(0, client.offset_encoding)
params.context = {
triggerKind = context.trigger.kind == 'trigger_character' and CompletionTriggerKind.TriggerCharacter
or CompletionTriggerKind.Invoked,
}
if context.trigger.kind == 'trigger_character' then params.context.triggerCharacter = context.trigger.character end
local _, request_id = client.request('textDocument/completion', params, function(err, result)
if err or result == nil then
resolve({ is_incomplete_forward = true, is_incomplete_backward = true, items = {} })
return
end
local items = result.items or result
local default_edit_range = result.itemDefaults and result.itemDefaults.editRange
for _, item in ipairs(items) do
item.client_id = client.id
-- score offset for deprecated items
-- todo: make configurable
if item.deprecated or (item.tags and vim.tbl_contains(item.tags, 1)) then item.score_offset = -2 end
-- set defaults
for key, value in pairs(result.itemDefaults or {}) do
if vim.tbl_contains(known_defaults, key) then item[key] = item[key] or value end
end
if default_edit_range and item.textEdit == nil then
local new_text = item.textEditText or item.insertText or item.label
if default_edit_range.replace ~= nil then
item.textEdit = {
replace = default_edit_range.replace,
insert = default_edit_range.insert,
newText = new_text,
}
else
item.textEdit = {
range = result.itemDefaults.editRange,
newText = new_text,
}
end
end
end
resolve({
is_incomplete_forward = result.isIncomplete or false,
is_incomplete_backward = true,
items = items,
})
end)
-- cancellation function
return function()
if request_id ~= nil then client.cancel_request(request_id) end
end
end)
end
return completion
|