diff options
Diffstat (limited to 'lua/blink/cmp/sources/lsp/completion.lua')
| -rw-r--r-- | lua/blink/cmp/sources/lsp/completion.lua | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/lua/blink/cmp/sources/lsp/completion.lua b/lua/blink/cmp/sources/lsp/completion.lua new file mode 100644 index 0000000..5d54280 --- /dev/null +++ b/lua/blink/cmp/sources/lsp/completion.lua @@ -0,0 +1,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 |
