summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--nvim/.config/nvim/lua/tobyvin/lsp/handlers.lua74
-rw-r--r--nvim/.config/nvim/lua/tobyvin/lsp/init.lua43
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