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