diff options
author | Toby Vincent <tobyv13@gmail.com> | 2022-10-26 19:31:00 -0500 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2022-10-26 19:31:00 -0500 |
commit | b0b23d4de6a3046387757ed921a3b45eeef88359 (patch) | |
tree | a751a202d9560d83a4cd066af9c5a43ad78aaf74 /nvim/.config | |
parent | ec33c53e7a7e29d33b5e1152397d4cbbdc6ed5eb (diff) |
feat(lsp): improve handlers, previews and floats
Diffstat (limited to 'nvim/.config')
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/keymaps.lua | 3 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/lsp.lua | 3 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua | 77 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua | 54 |
4 files changed, 81 insertions, 56 deletions
diff --git a/nvim/.config/nvim/lua/tobyvin/keymaps.lua b/nvim/.config/nvim/lua/tobyvin/keymaps.lua index 0f14731..8e3ff40 100644 --- a/nvim/.config/nvim/lua/tobyvin/keymaps.lua +++ b/nvim/.config/nvim/lua/tobyvin/keymaps.lua @@ -16,11 +16,14 @@ M.setup = function() vim.keymap.set("n", "gn", "<cmd>bnext<cr>", { desc = "bnext" }) vim.keymap.set("n", "gp", "<cmd>bprev<cr>", { desc = "bprev" }) vim.keymap.set("n", "gb", utils.buffer.bselect, { desc = "bselect" }) + vim.keymap.set("n", "gk", utils.documentation.open, { desc = "Documentation" }) + vim.keymap.set("n", "<leader>q", "<cmd>qall<cr>", { desc = "quit" }) vim.keymap.set("n", "<leader>c", utils.buffer.bdelete, { desc = "bdelete" }) vim.keymap.set("n", "<leader>x", "<cmd>close<cr>", { desc = "close" }) vim.keymap.set("n", "<leader>z", "<cmd>tabclose<cr>", { desc = "tabclose" }) vim.keymap.set("n", "<leader>w", "<cmd>write<cr>", { desc = "write" }) + vim.keymap.set("n", "<C-u>", "<C-u>zz", { desc = "Up half page and center" }) vim.keymap.set("n", "<C-d>", "<C-d>zz", { desc = "Down half page and center" }) vim.keymap.set("n", "<a-j>", "<CMD>m +1<CR>", { desc = "Move line down" }) diff --git a/nvim/.config/nvim/lua/tobyvin/lsp.lua b/nvim/.config/nvim/lua/tobyvin/lsp.lua index 8aadee6..2dd1678 100644 --- a/nvim/.config/nvim/lua/tobyvin/lsp.lua +++ b/nvim/.config/nvim/lua/tobyvin/lsp.lua @@ -12,7 +12,7 @@ lsp.setup = function() lsp.formatting.setup() vim.api.nvim_create_autocmd("LspAttach", { - group = vim.api.nvim_create_augroup("tobyvin_lsp", { clear = true }), + group = vim.api.nvim_create_augroup("tobyvin_lsp", { clear = true }), desc = "lsp", callback = function(args) local bufnr = args.buf @@ -20,7 +20,6 @@ lsp.setup = function() utils.keymap.group("n", "<leader>l", { desc = "LSP", buffer = bufnr }) vim.keymap.set("n", "<leader>L", "<CMD>LspInfo<CR>", { desc = "LSP info" }) - vim.keymap.set("n", "<leader>k", utils.documentation.open, { desc = "Documentation", buffer = bufnr }) vim.api.nvim_exec_autocmds("User", { pattern = "LspAttach", data = { client_id = client.id } }) end, }) diff --git a/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua b/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua index 66dcc7a..761b1e6 100644 --- a/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua +++ b/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua @@ -1,59 +1,39 @@ ----@diagnostic disable: missing-parameter +local utils = require("tobyvin.utils") local M = {} -M.goto_handler = function(method) - local callback = vim.lsp.handlers[method] +M.wrap_handler = function(method, handler) + handler = vim.F.if_nil(handler, vim.lsp.handlers[method]) return function(err, result, ctx, config) if result == nil or vim.tbl_isempty(result) then vim.notify("No location found", vim.log.levels.INFO, { title = "[LSP] " .. ctx.method }) return nil end - -- workaround for LSPs returning two results on (2) anonymous function (1) variable assignments, e.g. this func - if ctx.method == "textDocument/definition" and vim.tbl_islist(result) and #result > 1 then - for _, k in pairs(vim.tbl_keys(result[1])) do - if - (k == "range" or k == "targetRange") - and result[1][k].start ~= nil - and result[1][k].start.line == result[2][k].start.line - then - result[2][k].start = result[1][k].start - table.remove(result, 1) - break - end - end - end - - if vim.tbl_islist(result) and #result == 1 then + if vim.tbl_islist(result) then result = result[1] end - callback(err, result, ctx, config) + handler(err, result, ctx, config) end end -M.preview_handler = function(method) - local preview_callback = function(_, result, _, _) - if vim.tbl_islist(result) then - vim.lsp.util.preview_location(result[1]) - else - vim.lsp.util.preview_location(result) - end - end +M.with_float = function(name) + local method = string.format("textDocument/%s", name) + local handler = M.wrap_handler(method, function(_, result) + vim.lsp.util.preview_location(result, { + focus_id = "preview_" .. name, + close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" }, + border = "single", + scope = "cursor", + }) + end) return function() + ---@diagnostic disable-next-line: missing-parameter local params = vim.lsp.util.make_position_params() - return vim.lsp.buf_request(0, method, params, M.goto_handler(preview_callback)) + return vim.lsp.buf_request(0, method, params, handler) end end -M.preview = { - definition = M.preview_handler("textDocument/definition"), - declaration = M.preview_handler("textDocument/declaration"), - type_definition = M.preview_handler("textDocument/type_definition"), - implementation = M.preview_handler("textDocument/implementation"), - references = M.preview_handler("textDocument/references"), -} - M.setup = function() vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.handlers["textDocument/publishDiagnostics"], { @@ -81,12 +61,12 @@ M.setup = function() local bufnr = args.buf local client = vim.lsp.get_client_by_id(args.data.client_id) - if client.name ~= "rust-analyzer" then - vim.lsp.handlers["textDocument/definition"] = M.goto_handler("textDocument/definition") - vim.lsp.handlers["textDocument/declaration"] = M.goto_handler("textDocument/declaration") - vim.lsp.handlers["textDocument/type_definition"] = M.goto_handler("textDocument/type_definition") - vim.lsp.handlers["textDocument/implementation"] = M.goto_handler("textDocument/implementation") - vim.lsp.handlers["textDocument/references"] = M.goto_handler("textDocument/references") + if client.name ~= "rust_analyzer" then + vim.lsp.handlers["textDocument/definition"] = M.wrap_handler("textDocument/definition") + vim.lsp.handlers["textDocument/declaration"] = M.wrap_handler("textDocument/declaration") + vim.lsp.handlers["textDocument/type_definition"] = M.wrap_handler("textDocument/type_definition") + vim.lsp.handlers["textDocument/implementation"] = M.wrap_handler("textDocument/implementation") + vim.lsp.handlers["textDocument/references"] = M.wrap_handler("textDocument/references") end if client.server_capabilities["definitionProvider"] then @@ -102,11 +82,12 @@ M.setup = function() vim.keymap.set("n", "gi", vim.lsp.buf.implementation, { desc = "Implementation", buffer = bufnr }) vim.keymap.set("n", "gr", vim.lsp.buf.references, { desc = "References", buffer = bufnr }) - vim.keymap.set("n", "g<C-d>", M.preview.definition, { desc = "Definition", buffer = bufnr }) - vim.keymap.set("n", "g<CS-D>", M.preview.declaration, { desc = "Preview Declaration", buffer = bufnr }) - vim.keymap.set("n", "g<C-t>", M.preview.type_definition, { desc = "Preview Type", buffer = bufnr }) - vim.keymap.set("n", "g<C-i>", M.preview.implementation, { desc = "Preview Implementation", buffer = bufnr }) - vim.keymap.set("n", "g<C-r>", M.preview.references, { desc = "Preview References", buffer = bufnr }) + utils.keymap.group("n", "gf", { desc = "Float" }) + vim.keymap.set("n", "gfd", M.with_float("definition"), { desc = "Definition", buffer = bufnr }) + vim.keymap.set("n", "gfD", M.with_float("declaration"), { desc = "Declaration", buffer = bufnr }) + vim.keymap.set("n", "gft", M.with_float("type_definition"), { desc = "Type", buffer = bufnr }) + vim.keymap.set("n", "gfi", M.with_float("implementation"), { desc = "Implementation", buffer = bufnr }) + vim.keymap.set("n", "gfr", M.with_float("references"), { desc = "References", buffer = bufnr }) vim.keymap.set("n", "<leader>la", vim.lsp.buf.code_action, { desc = "Code Action", buffer = bufnr }) vim.keymap.set("n", "<leader>ll", vim.lsp.codelens.run, { desc = "Codelens", buffer = bufnr }) diff --git a/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua b/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua index 7be3a4a..6f4d57d 100644 --- a/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua +++ b/nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua @@ -3,6 +3,7 @@ local lsp = require("tobyvin.lsp") local M = { codelldb = "/usr/lib/codelldb/adapter/codelldb", liblldb = "/usr/lib/codelldb/lldb/lib/liblldb.so", + popup_id = "", } M.setup = function() @@ -12,13 +13,53 @@ M.setup = function() return end + local function parse_lines(t) + local ret = {} + + local name = t.name + local text = "// Recursive expansion of the " .. name .. " macro" + table.insert(ret, "// " .. string.rep("=", string.len(text) - 3)) + table.insert(ret, text) + table.insert(ret, "// " .. string.rep("=", string.len(text) - 3)) + table.insert(ret, "") + + local expansion = t.expansion + for string in string.gmatch(expansion, "([^\n]+)") do + table.insert(ret, string) + end + + return ret + end + + local handler = function(_, result) + if result == nil then + vim.api.nvim_out_write("No macro under cursor!\n") + return + end + + local contents = parse_lines(result) + local opts = { + focus_id = "expand_macro", + close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" }, + border = "single", + scope = "cursor", + } + vim.lsp.util.open_floating_preview(contents, "rust", opts) + end + + require("rust-tools.expand_macro").expand_macro = function() + ---@diagnostic disable-next-line: missing-parameter + local params = vim.lsp.util.make_position_params() + rust_tools.utils.request(0, "rust-analyzer/expandMacro", params, handler) + end + vim.api.nvim_create_autocmd("LspAttach", { - group = vim.api.nvim_create_augroup("tobyvin_rust-tools", { clear = true }), + group = vim.api.nvim_create_augroup("tobyvin_rust-tools", { clear = true }), desc = "setup rust-tools", callback = function(args) local bufnr = args.buf local client = vim.lsp.get_client_by_id(args.data.client_id) - if client.name ~= "rust-analyzer" then + if client.name ~= "rust_analyzer" then return end @@ -26,11 +67,12 @@ M.setup = function() local debuggables = rust_tools.debuggables.debuggables local open_cargo_toml = rust_tools.open_cargo_toml.open_cargo_toml local external_docs = rust_tools.external_docs.open_external_docs + local expand_macro = rust_tools.expand_macro.expand_macro - utils.keymap.group("n", "<leader>r", { desc = "Run" }) - vim.keymap.set("n", "<leader>rr", runnables, { desc = "Runnables", buffer = bufnr }) - vim.keymap.set("n", "<leader>rd", debuggables, { desc = "Debug", buffer = bufnr }) - vim.keymap.set("n", "<leader>ro", open_cargo_toml, { desc = "Open Cargo.toml", buffer = bufnr }) + vim.keymap.set("n", "<leader>dd", debuggables, { desc = "Debug", buffer = bufnr }) + vim.keymap.set("n", "<leader>lr", runnables, { desc = "Run", buffer = bufnr }) + vim.keymap.set("n", "<leader>lo", open_cargo_toml, { desc = "Open Cargo.toml", buffer = bufnr }) + vim.keymap.set("n", "<leader>le", expand_macro, { desc = "Expand macro", buffer = bufnr }) utils.documentation.register("rust", external_docs) end, |