Files

111 lines
2.6 KiB
Lua

local SNIPPET_FORMAT = vim.lsp.protocol.InsertTextFormat.Snippet
local SNIPPET_KIND = vim.lsp.protocol.CompletionItemKind.Snippet
---@param raw lsp.CompletionItem
---@return string
local function label_stem(raw)
return raw.label:match("[^(]+") or raw.label
end
---@param raw lsp.CompletionItem
---@return string
local function edit_text(raw)
if raw.textEdit then
return raw.textEdit.newText
end
return raw.insertText or raw.label
end
---@param raw lsp.CompletionItem
---@return string
local function get_word(raw)
if raw.insertTextFormat == SNIPPET_FORMAT then
return raw.filterText or label_stem(raw)
end
return edit_text(raw)
end
---@param raw lsp.CompletionItem
---@return string
local function get_abbr(raw)
local abbr = label_stem(raw)
if raw.kind == SNIPPET_KIND then
abbr = abbr .. "~"
end
return abbr
end
---@param raw lsp.CompletionItem
---@return string?
local function get_detail(raw)
return raw.detail or vim.tbl_get(raw, "labelDetails", "description")
end
---@param raw lsp.CompletionItem
---@return string?
local function get_doc(raw)
local doc = raw.documentation
if not doc then
return nil
end
return doc.value or doc
end
---@param raw lsp.CompletionItem
---@return string?
local function get_snippet(raw)
if raw.insertTextFormat == SNIPPET_FORMAT then
return edit_text(raw)
end
return nil
end
---@class ow.lsp.completion.Item
---@field word string
---@field abbr string
---@field detail string?
---@field doc string?
---@field snippet string?
---@field client_id integer
---@field raw lsp.CompletionItem
local Item = {}
Item.__index = Item
---@param raw lsp.CompletionItem
---@param client_id integer
---@return ow.lsp.completion.Item
function Item.from_lsp(raw, client_id)
return setmetatable({
word = get_word(raw),
abbr = get_abbr(raw),
detail = get_detail(raw),
doc = get_doc(raw),
snippet = get_snippet(raw),
client_id = client_id,
raw = raw,
}, Item)
end
---@param resolved lsp.CompletionItem
function Item:apply_resolved(resolved)
self.raw = vim.tbl_deep_extend("force", self.raw, resolved)
self.detail = get_detail(self.raw)
self.doc = get_doc(self.raw)
if self.snippet then
self.snippet = edit_text(self.raw)
end
end
---@param completed vim.v.completed_item
---@return ow.lsp.completion.Item?
function Item.from_user_data(completed)
local t = vim.tbl_get(completed, "user_data", "ow", "item")
if t then
return setmetatable(t, Item)
end
return nil
end
return Item