From 2b78176dde9036658492591fcb993143f45e9c13 Mon Sep 17 00:00:00 2001 From: "Schmidt, Tibor" Date: Sun, 7 Jan 2024 03:20:55 +0100 Subject: [PATCH] chore: backup wip --- lua/gp/init.lua | 141 +++++++++++++++++++++++++---------- lua/gp/lsp/ft/c.lua | 46 ++++++++++++ lua/gp/lsp/ft/cpp.lua | 86 +++++++++++++++++++++ lua/gp/lsp/ft/go.lua | 37 ++++++--- lua/gp/lsp/ft/javascript.lua | 2 +- lua/gp/lsp/ft/lua.lua | 2 +- lua/gp/lsp/ft/python.lua | 23 +++++- lua/gp/lsp/ft/typescript.lua | 2 +- lua/gp/lsp/init.lua | 27 +++++-- 9 files changed, 303 insertions(+), 63 deletions(-) create mode 100644 lua/gp/lsp/ft/c.lua create mode 100644 lua/gp/lsp/ft/cpp.lua diff --git a/lua/gp/init.lua b/lua/gp/init.lua index 02afabbe..e98da080 100644 --- a/lua/gp/init.lua +++ b/lua/gp/init.lua @@ -3260,14 +3260,45 @@ M.cmd.LspCompletion = function(params) end, {}) end -M.cmd.LspProbe = function(params) +local function simplify_structure(table) + -- Function to merge two tables + local function merge_tables(t1, t2) + for k, v in pairs(t2) do + if type(v) == "table" and type(t1[k] or false) == "table" then + merge_tables(t1[k], v) + else + t1[k] = v + end + end + end + + -- Recursive function to simplify the structure + local function simplify(t) + if t["completion"] then + merge_tables(t, t["completion"]) + t["completion"] = nil + end + for k, v in pairs(t) do + if type(v) == "table" then + simplify(v) + end + end + end + + simplify(table) +end + +---@param callback function receives the LSP probe result +---@param max_recursion number +---@param resolve_imports boolean +M.lspProbe = function(callback, max_recursion, resolve_imports) local lsp = require("gp.lsp") local buf = vim.api.nvim_get_current_buf() local filetype = vim.api.nvim_buf_get_option(buf, "filetype") - local probe_template = lsp.get_probe_template(filetype) - if not probe_template then + local template = lsp.get_probe_template(filetype) + if not template then M.warning( "No probe template for filetype: " .. filetype @@ -3305,16 +3336,11 @@ M.cmd.LspProbe = function(params) M.spinner.stop_spinner() - local tbuf = vim.api.nvim_create_buf(false, true) - -- vim.api.nvim_buf_set_lines(tbuf, 0, -1, false, vim.split(vim.json.encode(results), "\n")) - vim.api.nvim_buf_set_lines( - tbuf, - 0, - -1, - false, - vim.split(vim.inspect(results) .. "\n\n" .. vim.json.encode(results), "\n") - ) - vim.api.nvim_win_set_buf(0, tbuf) + -- simplify_structure(results) + + if callback then + callback(results) + end end) end local queue = require("gp.queue").create(cleanup) @@ -3324,13 +3350,11 @@ M.cmd.LspProbe = function(params) local ignored_items = lsp.get_ignored_items(filetype) local no_complete = lsp.get_no_complete_items(filetype) - print(vim.inspect(no_complete)) - M._H.undojoin(buf) - vim.api.nvim_buf_set_lines(buf, first_line + 1, first_line + 1, false, vim.split(probe_template, "\n")) + vim.api.nvim_buf_set_lines(buf, first_line + 1, first_line + 1, false, template.lines) local function completion_handler(kinds, root, output, level) - if level > 2 then + if not kinds or level > max_recursion then queue.runNextTask() return end @@ -3355,44 +3379,66 @@ M.cmd.LspProbe = function(params) queue.addTask(function(data) first_line = vim.api.nvim_buf_get_extmark_by_id(buf, ns_id, ex_id, {})[1] - lsp.hover(first_line + 3, #line - #affix.suffix, buf, function(contents) + lsp.hover(first_line + template.insert_line, #line - #affix.suffix, buf, function(contents) if contents then - output[data.kind][data.item].detail = contents[1]:gsub("{.*", ""):gsub("[ ]*$", "") - -- results[data.kind][data.item].detail = contents + local _kind_pattern = "^." .. data.kind:lower() .. ".%s*" + output[data.kind][data.item].detail = + contents[1]:gsub("{.*", ""):gsub("[ ]*$", ""):gsub(_kind_pattern, "") end queue.runNextTask() end) end, { kind = kind, item = item, detail = detail }) if affix.suffix ~= "" and not (no_complete[kind] and no_complete[kind][item]) then - queue.addTask(function(data) - lsp.completion(first_line + 3, #line, buf, function(item_kinds) + queue.addTask(function(d) + if not resolve_imports and d.kind == "Module" then + queue.runNextTask() + return + end + lsp.completion(first_line + template.insert_line, #line, buf, function(item_kinds) if item_kinds then - if not output[data.kind][data.item].completion then - output[data.kind][data.item].completion = item_kinds - output[data.kind][data.item].completion_line = data.line - queue.runNextTask() - return + if not output[d.kind][d.item].completion then + output[d.kind][d.item].completion = item_kinds + output[d.kind][d.item].prefix = d.line + else + -- keep only the longest completion + local ilen = #vim.json.encode(item_kinds) + local clen = #vim.json.encode(output[d.kind][d.item].completion) + local cprefix = #vim.json.encode(output[d.kind][d.item].prefix) + if ilen > clen or (ilen == clen and #d.line < cprefix) then + output[d.kind][d.item].completion = item_kinds + output[d.kind][d.item].prefix = d.line + end end - -- keep only the longest completion - local ilen = #vim.json.encode(item_kinds) - local clen = #vim.json.encode(output[data.kind][data.item].completion) - local cline = #vim.json.encode(output[data.kind][data.item].completion_line) - if ilen > clen or (ilen == clen and #data.line < cline) then - output[data.kind][data.item].completion = item_kinds - output[data.kind][data.item].completion_line = data.line + local cl = output[d.kind][d.item].completion + if cl[d.kind] then + cl[d.kind][d.item] = nil + if next(cl[d.kind]) == nil then + cl[d.kind] = nil + end end end queue.runNextTask() end, ignored_items) - end, { kind = kind, item = item, detail = detail, line = line:gsub("^%s*(.-)%s*$", "%1") }) + end, { + kind = kind, + item = item, + detail = detail, + line = line:gsub("^%s*(.-)%s*$", "%1"), + }) end queue.addTask(function() first_line = vim.api.nvim_buf_get_extmark_by_id(buf, ns_id, ex_id, {})[1] M._H.undojoin(buf) - vim.api.nvim_buf_set_lines(buf, first_line + 2, first_line + 3, false, {}) + vim.api.nvim_buf_set_lines( + buf, + first_line + template.insert_line - 1, + first_line + template.insert_line, + false, + {} + ) queue.runNextTask() end) end @@ -3400,10 +3446,10 @@ M.cmd.LspProbe = function(params) queue.addTask(function(data) local i = output[data.kind][data.item] if type(i) == "table" then - if i.completion and i.completion_line then + if i.completion and i.prefix then completion_handler( i.completion, - { prefix = i.completion_line, kind = data.kind }, + { prefix = i.prefix, kind = data.kind, item = data.item }, i.completion, level + 1 ) @@ -3423,9 +3469,24 @@ M.cmd.LspProbe = function(params) queue.runNextTask() end - lsp.completion(first_line + 1, 0, buf, function(kinds) - completion_handler(kinds, { prefix = "", kind = "" }, results, 1) + lsp.completion(first_line + template.insert_line, 0, buf, function(kinds) + completion_handler(kinds, { prefix = "", kind = "", item = "" }, results, 1) end, ignored_items) end +M.cmd.LspProbe = function(params) + M.lspProbe(function(results) + local tbuf = vim.api.nvim_create_buf(false, true) + -- vim.api.nvim_buf_set_lines(tbuf, 0, -1, false, vim.split(vim.json.encode(results), "\n")) + vim.api.nvim_buf_set_lines( + tbuf, + 0, + -1, + false, + vim.split(vim.inspect(results) .. "\n\n" .. vim.json.encode(results), "\n") + ) + vim.api.nvim_win_set_buf(0, tbuf) + end, 2, false) +end + return M diff --git a/lua/gp/lsp/ft/c.lua b/lua/gp/lsp/ft/c.lua new file mode 100644 index 00000000..bf42e482 --- /dev/null +++ b/lua/gp/lsp/ft/c.lua @@ -0,0 +1,46 @@ +return { + template = "\n\nvoid gp_lsp_probe() {\n \n}", + affixes = { + Class = { { prefix = " (*", suffix = "). " }, { prefix = " ", suffix = ". " } }, + Variable = { { prefix = " (*", suffix = "). " }, { prefix = " ", suffix = ". " } }, + Struct = { { prefix = " (*", suffix = "). " }, { prefix = " ", suffix = ". " } }, + Module = { { prefix = " ", suffix = ". " } }, + Interface = { { prefix = " ", suffix = ". " } }, + Field = { { prefix = " ", suffix = ". " } }, + }, + no_complete = {}, + ignore = { + Function = { + ["gp_lsp_probe()"] = "void", + }, + Keyword = { + _Bool = {}, + _Complex = {}, + _Imaginary = {}, + _Nonnull = {}, + _Null_unspecified = {}, + _Nullable = {}, + __FUNCTION__ = {}, + __PRETTY_FUNCTION__ = {}, + __auto_type = {}, + __func__ = {}, + char = {}, + const = {}, + double = {}, + enum = {}, + extern = {}, + float = {}, + int = {}, + long = {}, + restrict = {}, + short = {}, + signed = {}, + static = {}, + struct = {}, + union = {}, + unsigned = {}, + void = {}, + volatile = {}, + }, + }, +} diff --git a/lua/gp/lsp/ft/cpp.lua b/lua/gp/lsp/ft/cpp.lua new file mode 100644 index 00000000..200f3869 --- /dev/null +++ b/lua/gp/lsp/ft/cpp.lua @@ -0,0 +1,86 @@ +return { + template = "\n\nvoid gp_lsp_probe() {\n \n}", + affixes = { + Class = { + { prefix = " ", suffix = ":: " }, + { prefix = " ", suffix = "-> " }, + { prefix = " ", suffix = ". " }, + }, + Variable = { + { prefix = " ", suffix = ":: " }, + { prefix = " ", suffix = "-> " }, + { prefix = " ", suffix = ". " }, + }, + Struct = { + { prefix = " ", suffix = ":: " }, + { prefix = " ", suffix = "-> " }, + { prefix = " ", suffix = ". " }, + }, + Module = { + { prefix = " ", suffix = ":: " }, + { prefix = " ", suffix = "-> " }, + { prefix = " ", suffix = ". " }, + }, + Interface = { + { prefix = " ", suffix = ":: " }, + { prefix = " ", suffix = "-> " }, + { prefix = " ", suffix = ". " }, + }, + Field = { + { prefix = " ", suffix = ":: " }, + { prefix = " ", suffix = "-> " }, + { prefix = " ", suffix = ". " }, + }, + }, + no_complete = {}, + ignore = { + Function = { + ["gp_lsp_probe()"] = "void", + }, + Interface = { + Class = {}, + FILE = {}, + SEL = {}, + femode_t = {}, + fenv_t = {}, + fexcept_t = {}, + id = {}, + int_fast16_t = {}, + int_fast8_t = {}, + ucontext_t = {}, + }, + Keyword = { + _Nonnull = {}, + _Null_unspecified = {}, + _Nullable = {}, + __FUNCTION__ = {}, + __PRETTY_FUNCTION__ = {}, + __func__ = {}, + auto = {}, + bool = {}, + char = {}, + char16_t = {}, + char32_t = {}, + class = {}, + const = {}, + constexpr = {}, + double = {}, + enum = {}, + extern = {}, + float = {}, + int = {}, + long = {}, + operator = {}, + short = {}, + signed = {}, + static = {}, + struct = {}, + thread_local = {}, + union = {}, + unsigned = {}, + void = {}, + volatile = {}, + wchar_t = {}, + }, + }, +} diff --git a/lua/gp/lsp/ft/go.lua b/lua/gp/lsp/ft/go.lua index 51435619..b574ed66 100644 --- a/lua/gp/lsp/ft/go.lua +++ b/lua/gp/lsp/ft/go.lua @@ -1,5 +1,5 @@ return { - template = "func gp_lsp_probe() {\n \n}", + template = "\n\nfunc gp_lsp_probe() {\n \n}", affixes = { Class = { { prefix = " (*", suffix = "). " }, { prefix = " ", suffix = ". " } }, Variable = { { prefix = " (*", suffix = "). " }, { prefix = " ", suffix = ". " } }, @@ -10,20 +10,35 @@ return { }, no_complete = { Module = { - fmt = "", - time = "", + atomic = "", + bufio = "", + bytes = "", context = "", - strings = "", - sort = "", - sync = "", - rand = "", - json = "", + errors = "", + filepath = "", + flag = "", + fmt = "", http = "", - testing = "", - regexp = "", + io = "", + ioutil = "", + json = "", + log = "", + math = "", + net = "", os = "", + rand = "", reflect = "", - log = "", + regexp = "", + runtime = "", + sort = "", + strconv = "", + strings = "", + sync = "", + syscall = "", + template = "", + testing = "", + time = "", + unicode = "", }, }, ignore = { diff --git a/lua/gp/lsp/ft/javascript.lua b/lua/gp/lsp/ft/javascript.lua index d990dbf0..42369b3c 100644 --- a/lua/gp/lsp/ft/javascript.lua +++ b/lua/gp/lsp/ft/javascript.lua @@ -1,5 +1,5 @@ return { - template = "function gp_lsp_probe() {\n \n}", + template = "\n\nfunction gp_lsp_probe() {\n \n}", affixes = { Class = { { prefix = " ", suffix = ". " } }, Variable = { { prefix = " ", suffix = ". " } }, diff --git a/lua/gp/lsp/ft/lua.lua b/lua/gp/lsp/ft/lua.lua index c3d7b04f..af2e32d7 100644 --- a/lua/gp/lsp/ft/lua.lua +++ b/lua/gp/lsp/ft/lua.lua @@ -1,5 +1,5 @@ return { - template = "function gp_lsp_probe() {\n \n}", + template = "\n\nfunction gp_lsp_probe() {\n \n}", affixes = { Variable = { { prefix = " ", suffix = ". " } }, Field = { { prefix = " ", suffix = "" } }, diff --git a/lua/gp/lsp/ft/python.lua b/lua/gp/lsp/ft/python.lua index 1a562b67..32ee2730 100644 --- a/lua/gp/lsp/ft/python.lua +++ b/lua/gp/lsp/ft/python.lua @@ -1,12 +1,28 @@ return { - template = "def gp_lsp_probe():\n \n", + template = "\n\ndef gp_lsp_probe():\n \n", affixes = { Class = { { prefix = " ", suffix = ". " } }, Variable = { { prefix = " ", suffix = ". " } }, Module = { { prefix = " ", suffix = ". " } }, Function = { { prefix = " ", suffix = "" } }, - Method = { { prefix = " ", suffix = "" } }, - Constant = { { prefix = " ", suffix = "" } }, + Method = { { prefix = " ", suffix = "" } }, + Constant = { { prefix = " ", suffix = "" } }, + }, + no_complete = { + Module = { + -- sys = "", + os = "", + time = "", + random = "", + json = "", + requests = "", + logging = "", + subprocess = "", + multiprocessing = "", + threading = "", + datetime = "", + re = "", + }, }, ignore = { Method = { @@ -293,6 +309,7 @@ return { tuple = "", type = "", zip = "", + Flask = "", }, Function = { __build_class__ = "", diff --git a/lua/gp/lsp/ft/typescript.lua b/lua/gp/lsp/ft/typescript.lua index 6c0d19af..eccdb498 100644 --- a/lua/gp/lsp/ft/typescript.lua +++ b/lua/gp/lsp/ft/typescript.lua @@ -1,5 +1,5 @@ return { - template = "function gp_lsp_probe() {\n \n}", + template = "\n\nfunction gp_lsp_probe() {\n \n}", affixes = { Class = { { prefix = " ", suffix = ". " } }, Variable = { { prefix = " ", suffix = ". " } }, diff --git a/lua/gp/lsp/init.lua b/lua/gp/lsp/init.lua index fc90fa5e..3379e6a0 100644 --- a/lua/gp/lsp/init.lua +++ b/lua/gp/lsp/init.lua @@ -38,13 +38,27 @@ M.get_no_complete_items = function(filetype) end ---@param filetype string ----@return string|nil +---@return table|nil { lines = {string, ..}, insert_line = number } M.get_probe_template = function(filetype) + local lines = nil local status, data = pcall(require, "gp.lsp.ft." .. filetype) - if status and data and data.template then - return data.template + if not (status and data and data.template) then + return nil end - return nil + lines = vim.split(data.template, "\n") + + local insert_line = 0 + for i, line in ipairs(lines) do + if insert_line > 0 and line:match("^%s*$") then + insert_line = i + break + elseif not line:match("^%s*$") then + insert_line = i + end + end + + -- lines are put after extmark => + 1 + return { lines = lines, insert_line = insert_line + 1 } end ---@param filetype string @@ -143,14 +157,15 @@ M.completion = function(row, col, bufnr, callback, filtered) result = r.result.items and r.result.items or r.result end for _, item in ipairs(result) do + local label = item.label:match("^[%s•]*(.-)[%s•]*$") item.kind = vim.lsp.protocol.CompletionItemKind[item.kind] if item.kind ~= "Snippet" and item.kind ~= "Text" - and not (filtered and filtered[item.kind] and filtered[item.kind][item.label]) + and not (filtered and filtered[item.kind] and filtered[item.kind][label]) then items[item.kind] = items[item.kind] or {} - items[item.kind][item.label] = item.detail or "" + items[item.kind][label] = item.detail or "" end end end