aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorToby Vincent <tobyv13@gmail.com>2022-10-26 19:31:00 -0500
committerToby Vincent <tobyv13@gmail.com>2022-10-26 19:31:00 -0500
commitb0b23d4de6a3046387757ed921a3b45eeef88359 (patch)
treea751a202d9560d83a4cd066af9c5a43ad78aaf74
parentec33c53e7a7e29d33b5e1152397d4cbbdc6ed5eb (diff)
feat(lsp): improve handlers, previews and floats
-rw-r--r--nvim/.config/nvim/lua/tobyvin/keymaps.lua3
-rw-r--r--nvim/.config/nvim/lua/tobyvin/lsp.lua3
-rw-r--r--nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua77
-rw-r--r--nvim/.config/nvim/lua/tobyvin/plugins/rust-tools.lua54
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,