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