diff options
Diffstat (limited to 'nvim')
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua | 74 | ||||
-rw-r--r-- | nvim/.config/nvim/lua/tobyvin/lsp/init.lua | 43 |
2 files changed, 83 insertions, 34 deletions
diff --git a/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua b/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua index 3274314..c5fd5fa 100644 --- a/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua +++ b/nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua @@ -1,30 +1,66 @@ +---@diagnostic disable: missing-parameter local M = {} -local handler_hook = function(method, pre_hook, post_hook) - local original = vim.lsp.handlers[method] - vim.lsp.handlers[method] = function(...) - if pre_hook ~= nil then - pre_hook(...) +M.with_handler = function(callback) + return function(err, result, ctx, config) + if result == nil or vim.tbl_isempty(result) then + vim.lsp.log.info(ctx.method, "No location found") + vim.notify("No location found", vim.log.levels.INFO, { title = "[LSP] " .. ctx.method }) + return nil end - original(...) - if post_hook ~= nil then - post_hook(...) + + -- 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 + result = result[1] end + + callback(err, result, ctx, config) end end -M.setup = function() - handler_hook("textDocument/definition", function(_, result) - if not result or vim.tbl_isempty(result) then - vim.notify("[LSP] No definition found", vim.log.levels.INFO) +M.with_preview = 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) + end - handler_hook("textDocument/implementation", function(_, result) - if not result or vim.tbl_isempty(result) then - vim.notify("[LSP] No implementations found", vim.log.levels.INFO) - end - end) + return function() + local params = vim.lsp.util.make_position_params() + return vim.lsp.buf_request(0, method, params, M.with_handler(preview_callback)) + end +end + +M.preview = {} + +M.setup = function() + vim.lsp.handlers["textDocument/definition"] = M.with_handler(vim.lsp.handlers["textDocument/definition"]) + vim.lsp.handlers["textDocument/declaration"] = M.with_handler(vim.lsp.handlers["textDocument/declaration"]) + vim.lsp.handlers["textDocument/type_definition"] = M.with_handler(vim.lsp.handlers["textDocument/type_definition"]) + vim.lsp.handlers["textDocument/implementation"] = M.with_handler(vim.lsp.handlers["textDocument/implementation"]) + vim.lsp.handlers["textDocument/references"] = M.with_handler(vim.lsp.handlers["textDocument/references"]) + + M.preview.definition = M.with_preview("textDocument/definition") + M.preview.declaration = M.with_preview("textDocument/declaration") + M.preview.type_definition = M.with_preview("textDocument/type_definition") + M.preview.implementation = M.with_preview("textDocument/implementation") + M.preview.references = M.with_preview("textDocument/references") vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.handlers["textDocument/publishDiagnostics"], { @@ -35,7 +71,7 @@ M.setup = function() }) vim.lsp.handlers["window/showMessage"] = function(_, result, ctx) - vim.notify({ result.message }, 5 - result.type, { + vim.notify(result.message, 5 - result.type, { title = "[LSP] " .. vim.lsp.get_client_by_id(ctx.client_id), }) end diff --git a/nvim/.config/nvim/lua/tobyvin/lsp/init.lua b/nvim/.config/nvim/lua/tobyvin/lsp/init.lua index 73c2c0f..3bee629 100644 --- a/nvim/.config/nvim/lua/tobyvin/lsp/init.lua +++ b/nvim/.config/nvim/lua/tobyvin/lsp/init.lua @@ -1,19 +1,32 @@ local utils = require("tobyvin.utils") -local M = {} - -M.on_attach = function(client, bufnr) +local lsp = { + handlers = require("tobyvin.lsp.handlers"), + highlighting = require("tobyvin.lsp.highlighting"), + diagnostics = require("tobyvin.lsp.diagnostics"), + formatting = require("tobyvin.lsp.formatting"), + symbol = require("tobyvin.lsp.symbol"), +} + +lsp.on_attach = function(client, bufnr) if client.server_capabilities.definitionProvider then vim.bo[bufnr].tagfunc = "v:lua.vim.lsp.tagfunc" end + vim.keymap.set("n", "K", vim.lsp.buf.hover, { desc = "Hover", buffer = bufnr }) + vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, { desc = "Signature Help", buffer = bufnr }) + vim.keymap.set("n", "<leader>k", utils.documentation.open, { desc = "Documentation", buffer = bufnr }) vim.keymap.set("n", "gd", vim.lsp.buf.definition, { desc = "Definition", buffer = bufnr }) vim.keymap.set("n", "gD", vim.lsp.buf.declaration, { desc = "Declaration", buffer = bufnr }) vim.keymap.set("n", "gt", vim.lsp.buf.type_definition, { desc = "Type", buffer = bufnr }) 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", "K", vim.lsp.buf.hover, { desc = "Hover", buffer = bufnr }) - vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, { desc = "Signature Help", buffer = bufnr }) - vim.keymap.set("n", "<leader>k", utils.documentation.open, { desc = "Documentation", buffer = bufnr }) + + utils.keymap.group("n", "gp", { desc = "Preview", buffer = bufnr }) + vim.keymap.set("n", "gpd", lsp.handlers.preview.definition, { desc = "Definition", buffer = bufnr }) + vim.keymap.set("n", "gpD", lsp.handlers.preview.declaration, { desc = "Declaration", buffer = bufnr }) + vim.keymap.set("n", "gpt", lsp.handlers.preview.type_definition, { desc = "Type", buffer = bufnr }) + vim.keymap.set("n", "gpi", lsp.handlers.preview.implementation, { desc = "Implementation", buffer = bufnr }) + vim.keymap.set("n", "gpr", lsp.handlers.preview.references, { desc = "References", buffer = bufnr }) utils.keymap.group("n", "<leader>l", { desc = "LSP", buffer = bufnr }) vim.keymap.set("n", "<leader>li", "<CMD>LspInfo<CR>", { desc = "LSP info" }) @@ -22,27 +35,27 @@ M.on_attach = function(client, bufnr) vim.keymap.set("n", "<leader>ll", vim.lsp.codelens.run, { desc = "Codelens", buffer = bufnr }) -- disabled in favor of https://github.com/nvim-treesitter/nvim-treesitter-refactor#highlight-definitions - require("tobyvin.lsp.highlighting").on_attach(client, bufnr) - require("tobyvin.lsp.diagnostics").on_attach(client, bufnr) - require("tobyvin.lsp.formatting").on_attach(client, bufnr) - require("tobyvin.lsp.symbol").on_attach(client, bufnr) + lsp.highlighting.on_attach(client, bufnr) + lsp.diagnostics.on_attach(client, bufnr) + lsp.formatting.on_attach(client, bufnr) + lsp.symbol.on_attach(client, bufnr) require("lsp_signature").on_attach() end -M.config = function(config) +lsp.config = function(config) local capabilities = vim.lsp.protocol.make_client_capabilities() capabilities.textDocument.completion.completionItem.snippetSupport = true capabilities = require("cmp_nvim_lsp").update_capabilities(capabilities) return vim.tbl_deep_extend("keep", config or {}, { capabilities = capabilities, - on_attach = M.on_attach, + on_attach = lsp.on_attach, }) end -M.setup = function() - require("tobyvin.lsp.handlers").setup() +lsp.setup = function() + lsp.handlers.setup() require("tobyvin.lsp.diagnostics").setup() end -return M +return lsp |