Files
nvim/lua/lsp/completion/item.lua
T

91 lines
2.3 KiB
Lua

local SNIPPET = vim.lsp.protocol.InsertTextFormat.Snippet
---@param raw lsp.CompletionItem
---@return string?
local function edit_text(raw)
local edit = raw.textEdit
return (type(edit) == "table" and edit.newText) or raw.insertText
end
---@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 extract_doc(raw)
local doc = raw.documentation
if type(doc) == "table" then
return doc.value
end
---@cast doc string?
return doc
end
---@param raw lsp.CompletionItem
---@return string?
local function extract_detail(raw)
return raw.detail or vim.tbl_get(raw, "labelDetails", "description")
end
---@class ow.lsp.completion.Item
---@field word string
---@field abbr string
---@field menu 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)
local is_snippet = raw.insertTextFormat == SNIPPET
local abbr = label_stem(raw)
local word
if is_snippet then
word = raw.filterText or abbr
abbr = abbr .. "~"
else
word = edit_text(raw) or raw.label
end
return setmetatable({
word = word,
abbr = abbr,
menu = vim.tbl_get(raw, "labelDetails", "detail") or "",
detail = extract_detail(raw),
doc = extract_doc(raw),
snippet = is_snippet and (edit_text(raw) or raw.label) or nil,
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 = extract_detail(self.raw)
self.doc = extract_doc(self.raw)
if self.snippet then
self.snippet = edit_text(self.raw) or self.raw.label
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